在 python 中转换嵌套列表理解以使用 itertools 链
Convert nested list comprehension to use itertools chain in python
受到 Making a flat list out of list of lists in Python 中讨论的启发,我尝试转换它(在 some_directory 中获取文件和文件夹修改时间):
c = [os.path.getmtime(item) for root, d, files in os.walk(some_directory)
for item in [root] + map(lambda fi: os.path.join(root, fi), files)]
要使用itertools.chain:
c = map(os.path.getmtime,
itertools.chain.from_iterable([root] + map(lambda fi: join(root, fi), files)
for root, d, files in os.walk(some_directory)))
但我的分析显示它速度较慢而且看起来不太优雅。
那么在这种情况下如何使用链,即如何更优雅(更快)地生成中间列表?
或者我的情况是否有其他一些 itertools 函数?
编辑:
散列分析脚本:
import timeit
repeat = 10
setup ="""
import itertools
import os
join = os.path.join
path = r'C:\Dropbox\eclipse_workspaces'
c = []
"""
print "Original ", min(timeit.Timer("""[c.extend([join(root,dir) for dir in dirs] + [join(root,file) for file in files]) for root,dirs,files in os.walk(path)]""",
setup=setup).repeat(3, repeat))
print "For loop ", min(timeit.Timer("""for root, d, files in os.walk(path):
c.append(root)
c.extend(join(root, fi) for fi in files)""",
setup=setup).repeat(3, repeat))
print "Comprehension ", min(timeit.Timer('[item for r, d, f in os.walk(path) for item in [r] + map(lambda f: join(r, f), f)]',
setup=setup).repeat(3, repeat))
print "Comprehension + chain", min(timeit.Timer('[item for r, d, f in os.walk(path) for item in itertools.chain.from_iterable(([r], map(lambda fi: join(r, fi), f)))]',
setup=setup).repeat(3, repeat))
print "Itertools ", min(timeit.Timer("""[j for j in itertools.chain.from_iterable([root] + map(lambda fi: join(root, fi), files)
for root, d, files in os.walk(path))]""",
setup=setup).repeat(3, repeat))
似乎没有区别,但我在分析时遇到了一些奇怪的伪像,所以我没有 post 任何结果。我仍然对最快的方法感兴趣,最好使用 itertools
我认为在这里使用 chain
没有意义。 chain
当扁平化是它正在替换的理解的全部要点时最有用。如果您正在做更复杂的事情,那么坚持使用理解或生成器表达式可能会更容易。或者甚至将结构解压缩到一个显式的 for 循环中,这可能允许您避免当前代码中的列表连接之类的事情:
c = []
for root, d, files in os.walk(some_directory):
c.append(root)
c.extend(join(root, fi) for fi in files)
受到 Making a flat list out of list of lists in Python 中讨论的启发,我尝试转换它(在 some_directory 中获取文件和文件夹修改时间):
c = [os.path.getmtime(item) for root, d, files in os.walk(some_directory)
for item in [root] + map(lambda fi: os.path.join(root, fi), files)]
要使用itertools.chain:
c = map(os.path.getmtime,
itertools.chain.from_iterable([root] + map(lambda fi: join(root, fi), files)
for root, d, files in os.walk(some_directory)))
但我的分析显示它速度较慢而且看起来不太优雅。
那么在这种情况下如何使用链,即如何更优雅(更快)地生成中间列表?
或者我的情况是否有其他一些 itertools 函数?
编辑:
散列分析脚本:
import timeit
repeat = 10
setup ="""
import itertools
import os
join = os.path.join
path = r'C:\Dropbox\eclipse_workspaces'
c = []
"""
print "Original ", min(timeit.Timer("""[c.extend([join(root,dir) for dir in dirs] + [join(root,file) for file in files]) for root,dirs,files in os.walk(path)]""",
setup=setup).repeat(3, repeat))
print "For loop ", min(timeit.Timer("""for root, d, files in os.walk(path):
c.append(root)
c.extend(join(root, fi) for fi in files)""",
setup=setup).repeat(3, repeat))
print "Comprehension ", min(timeit.Timer('[item for r, d, f in os.walk(path) for item in [r] + map(lambda f: join(r, f), f)]',
setup=setup).repeat(3, repeat))
print "Comprehension + chain", min(timeit.Timer('[item for r, d, f in os.walk(path) for item in itertools.chain.from_iterable(([r], map(lambda fi: join(r, fi), f)))]',
setup=setup).repeat(3, repeat))
print "Itertools ", min(timeit.Timer("""[j for j in itertools.chain.from_iterable([root] + map(lambda fi: join(root, fi), files)
for root, d, files in os.walk(path))]""",
setup=setup).repeat(3, repeat))
似乎没有区别,但我在分析时遇到了一些奇怪的伪像,所以我没有 post 任何结果。我仍然对最快的方法感兴趣,最好使用 itertools
我认为在这里使用 chain
没有意义。 chain
当扁平化是它正在替换的理解的全部要点时最有用。如果您正在做更复杂的事情,那么坚持使用理解或生成器表达式可能会更容易。或者甚至将结构解压缩到一个显式的 for 循环中,这可能允许您避免当前代码中的列表连接之类的事情:
c = []
for root, d, files in os.walk(some_directory):
c.append(root)
c.extend(join(root, fi) for fi in files)