У меня есть папка A, как это:
A>>(B,C,D)(subfolders)>>both B,C and D have folders 1,2,3 each.
в этом случае подпапка "3" из B, C и D оказывается пустой.
Как вы проверяете и печатаете, какая папка бывает пустой во всех папках, например, чтобы выполнить поиск и распечатать номер "3", поскольку это единственная вложенная папка, которая пуста во всех папках B, C и D?
Код, который я пробовал:
for i in glob.iglob('**/Desktop/A/**' ,recursive = True):
if not os.listdir(i):
print(f'{i} is empty everywhere' + '\n')
который не работает.
Все папки имеют одинаковые подпапки (имя), но некоторые из них пусты. Мне нужно найти пустоты во всех этих папках и распечатать их.
Нам нужны две функции из модуля os
from os import walk
from os.path import join
Нам нужна начальная точка
dir = '/your/top/directory'
walk
возвращает генератор, итерацию на нем на каждом шаге у нас есть путь к текущему каталогу, список каталогов и список файлов, но мы не хотим итерации и интересуемся только списком каталогов в текущем каталоге, следовательно
dirs_l1 = next(walk(dir))[1]
обратите внимание, что, имея дело с генератором, вышесказанное не слишком расточительно...
Теперь у нас есть внутренний цикл в подкаталогах уровня 1 (l1 sd, sd, содержащийся в корне), чтобы создать список наборов каталогов уровня 2, который будет распакован и передан в set.intersection
, так что в dirs_l2
мы в конце концов, имеет набор всех каталогов уровня 2, которые присутствуют в каждом каталоге уровня 1
dirs_l2 = set.intersection(*[set(next(walk(join(dir, d)))[1]) for d in dirs_l1])
Мы делаем цикл на этих внутренних каталогах, присутствующих в каждом l1 sd, и используя all
встроенные, мы проверяем, что для каждого l1 sd все l2 sd пустые, в этом случае мы печатаем имя подкаталога l2, которое всегда пустое
for d2 in dirs_l2:
if all(next(walk(join(dir, d1, d2)))[1:] == ([],[]) for d1 in dirs_l1):
print(d2)
Пример
$ 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
$
Самое простое решение, о котором можно подумать, - это использовать карту, где ключи - это имена папок, а значения могут быть логическими. True
если пусто везде, False
otherwhise. Значение по умолчанию будет True
. Поэтому я бы использовал:
all_empty_map = {}
for i in glob.iglob('**/Desktop/A**', recursive=True):
cur_dir = os.path.basename(i)
all_empty_map[cur_dir] = all_empty_map.get(cur_dir, True) and not os.listdir(i)
for cur_dir, isempty in all_empty_map.items():
if isempty:
print cur_dir
Конечно, могут быть вещи, которые могут быть оптимизированы в коде.
A, B, C
) имеют один и тот же подкаталог, и вы хотите напечатать имя только одного подкаталога, если он пуст во всех трех каталогах? Так что, если папка3
будет пустой вA
иB
но не вC
, вы не хотите ее печатать?