在Python中,我想列出一组目录中的所有文件。我想得到的最好的是一个列表。但最多我设法制作了一个嵌套列表:
pics = os.path.expanduser('~/Pictures')
all_pics = [(d, os.listdir(d)) for d in os.listdir(pics)]
结果:
[('folder1', ['file1', 'file2', ...]), ('folder2', ['file1', ...]), ...]
我想要的是什么:
[('folder1' 'file1'), ('folder1', 'file2'), ..., ('folder2', 'file1'), ...]
我想得到的是一个简单的普通列表,无论是什么(可以是元组),只是为了它没有嵌套的东西,我在解析它的代码中不需要嵌套循环
如何使用列表推导来完成此操作?这样做给了我2套(目录名和文件名)的产品,这是错误的:
[(d, f) for f in os.listdir(os.path.join(pics, d)) for d in os.listdir(pics)]
答案 0 :(得分:5)
你得到了for循环的顺序错误。它应该是
all_pics = [(d, f)
for d in os.listdir(pics)
for f in os.listdir(os.path.join(pics, d))]
最外面的循环,最里面的循环。
我想知道为什么你没有为NameError
获得d
。
答案 1 :(得分:4)
使用os.walk
是一个更好的主意:
all_pics = [(dir,file)
for dir,sub,files in os.walk(pics)
for file in files]
那么为什么这是一个更好的主意呢?
subdir/subdir/pic.jpg
)~/Pictures
中,则不会中断(如果您在文件上调用os.listdir
,则会获得OSError: [Errno 20] Not a directory
)os.walk
为您进行遍历,剩下的就是格式化输出答案 2 :(得分:1)
列表推导作为从一个列表到另一个列表的映射。正如另一张海报所指出的,你可以通过嵌套它们来做到这一点,但你确定你真的想要吗?在大多数情况下,你应该倾向于阅读所有其他内容 - 而且我不认为嵌套理解很容易理解。
What is wrong with? It might be marginally slower - but will you notice?
files = []
for d in os.listdir(pics):
for f in os.listdir(os.path.join(pics, d)):
files.append((d, f))
如果您不想在绝对必要之前生成列表,则可以使用生成器:
def get_file_mapping():
for d in os.listdir(pics):
for f in os.listdir(os.path.join(pics, d)):
yield (d, f)
files = list(get_file_mapping())
答案 3 :(得分:0)
l = [ [(d, f) for f in os.listdir(os.path.join(pics, d))] for d in os.listdir(pics) ]
l = sum(l, []) # flatten list of lists => list
答案 4 :(得分:0)
您只需要展平输出列表:
pics = os.path.expanduser('~/Pictures')
all_pics = reduce(lambda xs,ys: xs+ys, [(d, os.listdir(d)) for d in os.listdir(pics)])