在Python中,使用列表推导或for-each循环是否更好?

fro*_*die 36 python foreach coding-style list-comprehension

以下哪项更好用,为什么?

方法1:

for k, v in os.environ.items():
       print "%s=%s" % (k, v)
Run Code Online (Sandbox Code Playgroud)

方法2:

print "\n".join(["%s=%s" % (k, v) 
   for k,v in os.environ.items()])
Run Code Online (Sandbox Code Playgroud)

我倾向于引导第一个更容易理解,但这可能只是因为我是Python新手,列表理解对我来说仍然有些陌生.第二种方式是否更像Pythonic?我假设没有性能差异,但我可能错了.这两种技术的优点和缺点是什么?

(从Dive到Python的代码)

Ste*_*ski 38

如果正在为其副作用进行迭代(就像在"打印"示例中那样),则循环更清晰.

如果执行迭代以构建复合值,则列表推导通常更具可读性.

  • +1:列表理解来自函数式编程,而for循环来自命令式编程. (6认同)
  • 除非有理由不这样做,否则我最初会寻求可读性.在给出的示例中,没有理由尝试将打印速度提高几微秒.在更一般的情况下,如果您正在迭代表达式的副作用,那么副作用生成语句很可能比您使用的迭代构造花费更多时间. (5认同)

Ben*_*mes 25

您选择的特定代码示例并未证明列表理解的任何优势,因为它(错误地)用于打印的繁琐任务.在这个简单的例子中,我会选择简单的for循环.

在许多其他情况下,您需要为另一个函数或方法提供实际列表,并且列表理解是最简单,最易读的方法.

可以通过将print示例替换为涉及创建另一个实际列表的示例,通过在for循环的每次迭代中附加一个来清楚地显示列表comp的优越性的示例:

L = []
for x in range(10):
    L.append(x**2)
Run Code Online (Sandbox Code Playgroud)

给出相同L的:

L = [x**2 for x in range(10)]
Run Code Online (Sandbox Code Playgroud)


Tim*_*ker 15

我发现第一个例子更好 - 更简洁,更清晰,更易读.

在我看来,毕竟,最好的方式是你的意图:

程序应该编写供人们阅读,并且只是偶然为机器执行.

- 来自Abelson和Sussman的"计算机程序的结构和解释"

顺便说一下,既然你刚开始学习Python,就马上开始学习新的String Formatting语法:

for k, v in os.environ.items():
    print "{0}={1}".format(k, v)
Run Code Online (Sandbox Code Playgroud)


Wai*_*ung 13

列表理解的速度是显式循环的两倍多.基于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)]
Run Code Online (Sandbox Code Playgroud)

时间结果:

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
Run Code Online (Sandbox Code Playgroud)

列表理解大幅提升.

我同意,可读性应优先于性能优化.然而,可读性在旁观者眼中.当我第一次学习Python时,列表理解是一件令人难以理解的奇怪事情!:-O但是一旦我习惯它,它就变成了一个非常好的简写符号.如果你要精通Python,你必须掌握列表理解.