Python 我如何在列表理解中重写这个for循环

Python 我如何在列表理解中重写这个for循环,python,python-2.7,for-loop,list-comprehension,Python,Python 2.7,For Loop,List Comprehension,我得到了这样一个“for循环”: for dirctory in dirs: for item in os.walk(dirctory): for i in item[2]: i = os.path.join(item[0], i) if is_image(i): images.append(i) 我试着把它改写成列表理解,我试着这样做: images.extend(filter(is_im

我得到了这样一个“for循环”:

for dirctory in dirs:
    for item in os.walk(dirctory):
        for i in item[2]:
            i = os.path.join(item[0], i)
            if is_image(i):
                images.append(i)
我试着把它改写成列表理解,我试着这样做:

images.extend(filter(is_image, [item[0]+i for i in item[2] for item in os.walk(dirctory)]))
images.extend(filter(is_image, [(item[0]+i for i in item[2]) for item in os.walk(dirctory)]))
它表示UnboundLocalError:在赋值之前引用了局部变量“item”

所以我试了一下:

images.extend(filter(is_image, [item[0]+i for i in item[2] for item in os.walk(dirctory)]))
images.extend(filter(is_image, [(item[0]+i for i in item[2]) for item in os.walk(dirctory)]))
它说TypeError:强制使用Unicode:需要字符串或缓冲区,找到生成器

我在OS X中使用Python 2.7.4。

尝试以下方法:

[os.path.join(item[0], i) for directory in dirs for item in os.walk(dirctory) for i in item[2] if is_image(os.path.join(item[0], i))]

下面是如何实现的(这并不完全是我测试的)

但是,如果您注意的话,在这个解决方案中,您必须连接路径两次,所以直接的嵌套循环可能更有效

编辑:

在我的示例中,我通过扩展名查找Python文件,因此在这种情况下,列表理解不会受到路径/文件名双重连接的影响

def check_image(directory, file_name):
    file_name = os.path.join(directory, file_name)
    return is_image(file_name), file_name

[full_path
     for current_dir in dirs
     for parent_dir, _, files in os.walk(current_dir)
     for current_file in files
     for isimage, full_path in [check_image(parent_dir, current_file)]
         if isimage]

check\u image
函数用于避免两次应用
os.path.join

不是python专家,但是上面代码对应的列表理解可能有点长,很难阅读。它也有副作用,我想在列表中你通常会避免这样做。编辑啊nvm,我看你只打算用列表理解部分代码。哎呀。我想说它还是有点长,但我个人认为为了清晰易读,还是把它作为嵌套循环。问问你自己,为什么你想把它作为列表理解?在我看来,如果很难阅读和理解列表,那么理解并不是你想要的。想想看,其他人需要理解这个列表理解……代码中的一个缺陷是——将所有组件作为单个项来获取会降低可读性。在类似情况下,变量的显式命名比模糊索引更好。
all_directories=chain(*map(os.walk,dirs))
full_filenames=lambda root,dirs,files:map(lambda file:os.path.join(root,file),files)
image_files=filter(is_image,starmap(full_filenames,all_dirs)
还有什么好主意不使用os.walk来获取所有文件的路径吗?顺便说一句,os.image是一个输入错误吗?使用filter(),我只能使用os.path.join一次,这样会更好吗?比如:images.extend(filter(is_image,[os.path.join(p,f)表示p,\u,os.walk中的文件(directory)表示f文件中的文件)))