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

发布于 2024-09-01 11:37:39 字数 469 浏览 6 评论 0原文

以下哪项最好使用,为什么?

方法 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 新手,并且列表推导式对我来说仍然有些陌生。第二种方式是否被认为更Pythonic?我假设没有性能差异,但我可能是错的。这两种技术的优点和缺点是什么?

(代码取自深入Python

Which of the following is better to use and why?

Method 1:

for k, v in os.environ.items():
       print "%s=%s" % (k, v)

Method 2:

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

I tend to lead towards the first as more understandable, but that might just be because I'm new to Python and list comprehensions are still somewhat foreign to me. Is the second way considered more Pythonic? I'm assuming there's no performance difference, but I may be wrong. What would be the advantages and disadvantages of these 2 techniques?

(Code taken from Dive into Python)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

一江春梦 2024-09-08 11:37:39

如果迭代是为了其副作用而进行的(就像在“打印”示例中一样),那么循环会更清晰。

如果执行迭代是为了构建复合值,则列表推导式通常更具可读性。

If the iteration is being done for its side effect ( as it is in your "print" example ), then a loop is clearer.

If the iteration is executed in order to build a composite value, then list comprehensions are usually more readable.

夜还是长夜 2024-09-08 11:37:39

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

在许多其他情况下,您需要向另一个函数或方法提供实际列表,而列表理解是最简单且最具可读性的方法。

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

L = []
for x in range(10):
    L.append(x**2)

给出与以下相同的 L

L = [x**2 for x in range(10)]

The particular code examples you have chosen do not demonstrate any advantage of the list comprehension, because it is being (mis-)used for the trivial task of printing. In this simple case I would choose the simple for loop.

In many other cases, you will want to supply an actual list to another function or method, and the list comprehension is the easiest and most readable way to do that.

An example which would clearly show the superiority of the list comp could be made by replacing the print example with one involving creating another actual list, by appending to one on each iteration of the for loop:

L = []
for x in range(10):
    L.append(x**2)

Gives the same L as:

L = [x**2 for x in range(10)]
疯到世界奔溃 2024-09-08 11:37:39

我发现第一个示例更好 - 更简洁、更清晰且更具可读性。

毕竟,我认为,选择最能表达你的意图的方式:

程序应该是为人而写的
阅读,并且只是顺便阅读
执行的机器。

——摘自 Abelson 和 Sussman 的《计算机程序的结构和解释》

顺便说一句,既然你刚刚开始学习 Python,就开始学习 新字符串格式化语法 立即:

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

I find the first example better - less verbose, clearer and more readable.

In my opinion, go with what best gets your intention across, after all:

Programs should be written for people
to read, and only incidentally for
machines to execute.

-- from "Structure and Interpretation of Computer Programs" by Abelson and Sussman

By the way, since you're just starting to learn Python, start learning the new String Formatting syntax right away:

for k, v in os.environ.items():
    print "{0}={1}".format(k, v)
纸短情长 2024-09-08 11:37:39

列表理解的速度是显式循环的两倍多。基于 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 时,列表理解是一件我觉得很难理解的奇怪事情! :-O 但是一旦我习惯了它,它就变成了一个非常好的速记符号。如果你想精通 Python,你必须掌握列表理解。

List comprehension is more than twice as fast as explicit loop. Base on Ben James' variation, but replace the x**2 with a more trivial x+2 function, the two alternatives are:

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)]

Timing result:

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

List comprehension wins by a large margin.

I agree than readability should be a priority over performance optimization. However readability is in the eye of beholder. When I first learn Python, list comprehension is a weird thing I find hard to comprehend! :-O But once I got use to it, it becomes a really nice short hand notation. If you are to become proficient in Python you have to master list comprehension.

终陌 2024-09-08 11:37:39

我认为第一个是因为:

  • 它不会构建一个巨大的字符串。
  • 它不会构建一个巨大的列表(可以通过删除 [] 使用生成器轻松修复)。

在这两种情况下,您都以相同的方式访问项目(使用字典迭代器)。

The first one in my opinion, because:

  • It doesn't build a huge string.
  • It doesn't build a huge list (can easily be fixed with a generator, by removing the []).

In both cases, you access the items in the same way (using the dictionary iterator).

梨涡少年 2024-09-08 11:37:39

列表推导式应该在 C 级别运行,因此如果存在巨大的循环,列表推导式是不错的选择。

list comprehensions are supposed to be run at C level, so if there is huge loop, list comprehensions are good choice.

权谋诡计 2024-09-08 11:37:39

我同意@Ben,@Tim,@Steven:

  • 可读性是最重要的事情(做“导入这个”以提醒自己是什么)
  • 列表计算可能比迭代循环版本快很多,也可能不会快很多......取决于所进行的函数调用总数。
  • 如果您确实决定使用具有大型数据集的列表计算,则最好使用生成器表达式来代替

示例:

print "\n".join("%s=%s" % (k, v) for k,v in os.environ.iteritems())

在代码片段中上面,我做了两个更改...我用 genexp 替换了 listcomp,并将方法调用更改为 iteritems()。 [这种趋势正在向前发展,在 Python 3 中,iteritems() 取代并重命名为 items()。]

I agree with @Ben, @Tim, @Steven:

  • readability is the most important thing (do "import this" to remind yourself of what is)
  • a listcomp may or may not be much faster than an iterative-loop version... it depends on the total number of function calls that are made
  • if you do decide to go with listcomps with large datasets, it's better to use generator expressions instead

Example:

print "\n".join("%s=%s" % (k, v) for k,v in os.environ.iteritems())

in the code snippet above, I made two changes... I replaced the listcomp with a genexp, and I changed the method call to iteritems(). [this trend is moving forward as in Python 3, iteritems() replaces and is renamed to items().]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文