Python 如何在不制作产品的情况下进行嵌套列表理解?

Python 如何在不制作产品的情况下进行嵌套列表理解?,python,list-comprehension,Python,List Comprehension,在Python中,我想列出一组目录中的所有文件。我最想得到的就是一份清单。但我最多只能列出一个嵌套列表: pics = os.path.expanduser('~/Pictures') all_pics = [(d, os.listdir(d)) for d in os.listdir(pics)] 结果: [('folder1', ['file1', 'file2', ...]), ('folder2', ['file1', ...]), ...] 我想要的是: [('folder1' '

在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)]

你把for循环的顺序搞错了。应该是

all_pics = [(d, f)
            for d in os.listdir(pics)
            for f in os.listdir(os.path.join(pics, d))]
首先是最外层的环,最后是最内层的环


我想知道为什么您没有得到
d

namererror
,您只需要将输出列表展平:

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
pics = os.path.expanduser('~/Pictures')
all_pics = reduce(lambda xs,ys: xs+ys, [(d, os.listdir(d)) for d in os.listdir(pics)])

列表理解是从一个列表到另一个列表的映射。正如另一张海报所指出的那样,你可以通过嵌套它们来实现,但你确定你真的想这样做吗?在所有的情况下,你都应该喜欢可读性,而且我不认为嵌套的理解是容易理解的。
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())

使用
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]而不是目录
  • 它更简单:
    os.walk
    为您进行遍历,剩下的就是格式化输出

这将创建一个元组列表。显然,OP的
Pictures
目录中只有目录。我省略了我使用的筛选器(
os.path.isdir
),如果
pics
目录中有文件,此操作将失败。看看我的答案。@dancek:是的,但与问题无关。显然,OP感兴趣的目录中只有目录。问题是为什么OP的列表理解没有像预期的那样有效。Marmach:我实际上同意这是不相关的。很可能在将来的某个时候,OP将一个文件放入
~/Pictures
,脚本就会中断。我认为从“正确的方式”开始并没有什么害处,但从另一个角度来看,以后可能会有潜在的害处……我知道可读性,但在这种情况下,我只是想知道我做错了什么。