在Python中,使用列表理解还是使用for each循环更好?
以下哪项更适合使用?为什么 方法1:在Python中,使用列表理解还是使用for each循环更好?,python,coding-style,foreach,list-comprehension,Python,Coding Style,Foreach,List Comprehension,以下哪项更适合使用?为什么 方法1: for k, v in os.environ.items(): print "%s=%s" % (k, v) 方法2: print "\n".join(["%s=%s" % (k, v) for k,v in os.environ.items()]) 我倾向于以更容易理解的方式引导第一个列表,但这可能只是因为我对Python不熟悉,列表理解对我来说仍然有些陌生。第二种方式被认为更像蟒蛇吗?我假设没有性能差异,但我可能错了。这两种技术
for k, v in os.environ.items():
print "%s=%s" % (k, v)
方法2:
print "\n".join(["%s=%s" % (k, v)
for k,v in os.environ.items()])
我倾向于以更容易理解的方式引导第一个列表,但这可能只是因为我对Python不熟悉,列表理解对我来说仍然有些陌生。第二种方式被认为更像蟒蛇吗?我假设没有性能差异,但我可能错了。这两种技术的优缺点是什么
(代码取自)我认为第一个,因为:
- 它不会建立一个巨大的字符串
- 它不会生成一个庞大的列表(可以通过删除
轻松地用生成器修复)[]
在这两种情况下,您都以相同的方式访问项目(使用字典迭代器)。列表理解应该在C级别运行,因此如果存在巨大的循环,列表理解是一个不错的选择。我发现第一个示例更好——更不冗长、更清晰、更可读 在我看来,毕竟,用最能让人理解你意图的方式去做: 程序应该是为人编写的 阅读,只是为了 要执行的机器 --来自Abelson和Sussman的“计算机程序的结构和解释” 顺便说一下,由于您刚刚开始学习Python,请立即开始学习:
for k, v in os.environ.items():
print "{0}={1}".format(k, v)
您选择的特定代码示例并没有展示列表理解的任何优势,因为它被(错误地)用于琐碎的打印任务。在这个简单的例子中,我会选择简单的
for
循环
在许多其他情况下,您需要向另一个函数或方法提供一个实际的列表,而列表理解是最简单、最可读的方法
可以通过将print
示例替换为一个涉及创建另一个实际列表的示例,并在for
循环的每次迭代中添加到一个示例,来明确显示列表comp的优势:
L = []
for x in range(10):
L.append(x**2)
给出与以下内容相同的L
:
L = [x**2 for x in range(10)]
如果迭代是为了它的副作用而进行的(就像“打印”示例中那样),那么循环就更清晰了
如果执行迭代是为了构建复合值,那么列表理解通常更具可读性 列表理解的速度是显式循环的两倍多。基于Ben James的变体,但将x**2替换为更简单的x+2函数,两个备选方案是:
def foo(n):
L = []
for x in xrange(n):
L.append(x+2)
return L
def bar(n):
return [x+2 for x in xrange(n)]
计时结果:
In [674]: timeit foo(1000)
10000 loops, best of 3: 195 us per loop
In [675]: timeit bar(1000)
10000 loops, best of 3: 81.7 us per loop
列表理解以很大的优势获胜
我同意可读性应该优先于性能优化。然而,在旁观者眼中,可读性是存在的。当我第一次学习Python时,列表理解是一件我觉得很难理解的奇怪事情-但一旦我习惯了它,它就变成了一个非常好的速记符号。如果你想精通Python,你必须掌握列表理解。我同意@Ben、@Tim、@Steven的观点:
- 可读性是最重要的(请务必“导入此内容”以提醒自己
- listcomp可能比迭代循环版本快,也可能不快。。。它取决于所进行的函数调用的总数
- 如果您决定使用具有大型数据集的listcomps,最好使用生成器表达式
print "\n".join("%s=%s" % (k, v) for k,v in os.environ.iteritems())
在上面的代码片段中,我做了两个更改。。。我用genexp替换了listcomp,并将方法调用更改为
iteritems()
。[这一趋势正在向前发展,就像在Python 3中一样,iteritems()
替换并重命名为items()
)打印速度仍然很慢-追求可读性(用于循环)。一般来说,首先要考虑可读性。然后,当它看起来慢调和优化。除非您正在设计一个框架(库),否则一开始您可能会遇到难闻的代码。然后你会感觉到什么有效,什么无效。绝对-首先要保证可读性。当…时优化性能请注意,str.format()仅在python版本>=2.6中存在。您的示例的问题在于它很简单。为什么不实际使用问题中的代码来显示差异?可能有一些计时信息?另一个好处是,您可以将结果列表提供给另一个函数,或链/嵌套理解。+1:列表理解源于函数编程,for循环源于命令式编程。+1是关于何时使用循环与列表理解的简明解释。我同意可读性,但可读性并不是实际代码中的主要考虑因素。也许在演示代码中,可读性是最重要的。在现实世界中,表演有时是王道,尽管并非总是如此。发电机在使用时会被使用,因为它们会带来一些好处。OP问“哪个更好”。它以一种明显更好的方式完成工作(在某些情况下更少地浪费资源,在某些情况下更快,正如您的要求所示)。我最初会追求可读性,除非有理由不这样做。在给出的示例中,没有理由尝试将打印速度提高几微秒。在更一般的情况下,如果您迭代表达式的副作用,很可能副作用生成语句比您使用的迭代构造花费更多的时间。俗话说,过早优化是万恶之源。编写它是为了可读,这样,当您可以测试完成的程序并实际找出需要优化的地方时,您就了解了代码在做什么。确切地说,通过列表理解,您可以编写更多的高性能代码,而高级pythonistas可以理解这些代码,而不是更多,对于一年级学生来说,列表理解更能表达实际逻辑,接近集合生成器符号。一般来说,for循环必须“在头部执行”,才能看到它的功能。我还没有尝试过