编写更好的代码而不是2 for循环

时间:2012-04-14 07:23:09

标签: python list for-loop

我有2个循环,我想让它更好像列表理解或lambda或其他。 我怎么能实现同样的目标?

例如:

filename = ['a.txt', 'b.txt', 'c.txt']
for files in filename:
    for f in glob.glob(os.path.join(source_path, files)):
        print f
        ... some processing...

4 个答案:

答案 0 :(得分:27)

你的代码完全没问题。你只能通过引入不必要的复杂结构使它变得不那么清晰。

答案 1 :(得分:4)

您可以将两个for循环压缩为单个generator expression *,并使用新的for循环从中提取文件名。

for f in (f_ for files in filename
             for f_ in glob.glob(os.path.join(source_path, files))):
    print f
    # ...

正如另一个答案所说, 更好,这是 更糟 而你 不应该 使用它(我不确定这是否足够强调!)。理解正在发生的事情要困难得多,并且可能没有什么性能优势(事实上,额外的间接层意味着它可能会更慢)。

(*基本上相当于列表理解,但在这种情况下更好。)

答案 2 :(得分:4)

我会像下面这样做。原因是现在您可以分离搜索模式的形成,搜索和文件处理。如果它们不相关则更容易扩展。

如果您的系统有点异国情调(例如分布式网络驱动器),则包含glob和os.path.join的行是一个讨厌的行。虽然正如其他人提到的那样,两个循环完全没问题。

filename = ['a.txt', 'b.txt', 'c.txt']

searchPatterns = [os.path.join(source_path, files) for files in filename]

searchResults = [glob.glob(pattern) for pattern in searchPatterns]

fileListFlat = sum(searchResults,[])

for file in fileListFlat:
    print file

答案 3 :(得分:2)

当您必须向右扫描并向后扫描时,很难读取长表达式。当有很多局部变量,lambdas和理解,只是被parens和逗号分开时,几行就更糟了。仅在您的代码不再变得更长和更复杂的情况下使用它们 对于你的情况,我更愿意提取find作为权衡。但正如最佳答案所说,你的代码足够好。

from itertools import chain

find = lambda p: glob.glob(os.path.join(source_path, p))
for file in chain(map(find, filename)):
    """
    =) I like one-level indentation here.
    =( I don't know which file pattern is used currently,
       unless I use longer expression...
    """