<p>我们需要来自<code>os</code>模块的两个函数</p>
<pre><code>from os import walk
from os.path import join
</code></pre>
<p>我们需要一个起点</p>
<pre><code>dir = '/your/top/directory'
</code></pre>
<p><code>walk</code>返回一个生成器,在每一步对它进行迭代我们有当前目录的路径、目录列表和文件列表,但我们不想迭代,只对当前目录中的目录列表感兴趣,因此</p>
<pre><code>dirs_l1 = next(walk(dir))[1]
</code></pre>
<p>注意,必须处理一个发电机,以上不是太浪费。。。你知道吗</p>
<p>现在我们在级别1的子目录(l1sd,根目录中包含的sd)上有一个内部循环来创建级别2的目录集列表,这些目录集将被解压并传递给<code>set.intersection</code>,这样在<code>dirs_l2</code>中,我们最终会有一组级别2的所有目录,这些目录存在于级别1的每个<em>目录中</p>
<pre><code>dirs_l2 = set.intersection(*[set(next(walk(join(dir, d)))[1]) for d in dirs_l1])
</code></pre>
<p>我们在每个l1sd中存在的这些内部目录上做一个循环,并使用<code>all</code>内置项检查,对于每个l1sd,所有l2sd都是空的,在这种情况下,我们打印总是空的l2子目录的名称</p>
<pre><code>for d2 in dirs_l2:
if all(next(walk(join(dir, d1, d2)))[1:] == ([],[]) for d1 in dirs_l1):
print(d2)
</code></pre>
<hr/>
<p>一个例子</p>
<pre><code>$ cat A.py
from os import walk
from os.path import join
dir = './A'
dirs_l1 = next(walk(dir))[1]
dirs_l2 = set.intersection(*[set(next(walk(join(dir, d)))[1]) for d in dirs_l1])
for d2 in dirs_l2:
if all(next(walk(join(dir, d1, d2)))[1:] == ([], []) for d1 in dirs_l1): print(d2)
$ tree A
A
├── A
│ ├── 1
│ │ └── a
│ ├── 2
│ │ └── b
│ └── 3
├── B
│ ├── 1
│ │ └── a
│ ├── 2
│ │ └── b
│ └── 3
├── C
│ ├── 1
│ │ └── a
│ ├── 2
│ │ └── b
│ └── 3
└── D
├── 1
│ └── a
├── 2
│ └── b
└── 3
$ python A.py
3
$
</code></pre>