什么时候删除列表理解和Python方式? [英] When to drop list Comprehension and the Pythonic way?
问题描述
我创建了一条以以下方式将对象追加到列表的行
I created a line that appends an object to a list in the following manner
>>> foo = list()
>>> def sum(a, b):
... c = a+b; return c
...
>>> bar_list = [9,8,7,6,5,4,3,2,1,0]
>>> [foo.append(sum(i,x)) for i, x in enumerate(bar_list)]
[None, None, None, None, None, None, None, None, None, None]
>>> foo
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>>
线
[foo.append(sum(i,x)) for i, x in enumerate(bar_list)]
将给出一个pylint W1060表达式,但不会分配任何内容,但是由于我已经在使用foo列表来附加值,所以我不需要将List Comprehension行附加到某些东西上.
would give a pylint W1060 Expression is assigned to nothing, but since I am already using the foo list to append the values I don't need to assing the List Comprehension line to something.
我的问题更多是关于编程正确性的问题
我应该放弃列表理解而只使用简单的表达式吗?
Should I drop list comprehension and just use a simple for expression?
>>> for i, x in enumerate(bar_list):
... foo.append(sum(i,x))
还是有一种正确的方法来同时使用两个列表理解和什么都不分配?
or is there a correct way to use both list comprehension an assign to nothing?
答案
谢谢@ user2387370,@ kindall和@Martijn Pieters.对于其余的注释,我使用append是因为我没有使用list(),所以我没有使用i + x,因为这只是一个简化的示例.
Thank you @user2387370, @kindall and @Martijn Pieters. For the rest of the comments I use append because I'm not using a list(), I'm not using i+x because this is just a simplified example.
我将其保留为以下内容:
I left it as the following:
histogramsCtr = hist_impl.HistogramsContainer()
for index, tupl in enumerate(local_ranges_per_histogram_list):
histogramsCtr.append(doSubHistogramData(index, tupl))
return histogramsCtr
推荐答案
是的,这是不好的样式.列表理解是建立一个列表.您正在建立一个完整的 None
列表,然后将其丢弃.您实际期望的结果是此工作的副作用.
Yes, this is bad style. A list comprehension is to build a list. You're building a list full of None
s and then throwing it away. Your actual desired result is a side effect of this effort.
为什么不首先使用列表理解来定义 foo
?
Why not define foo
using the list comprehension in the first place?
foo = [sum(i,x) for i, x in enumerate(bar_list)]
如果不是列表而是其他容器类,如您在另一个答案的注释中所述,请编写该类以在其构造函数中接受一个Iterable(或者,如果不是您的代码,请将该类子类化)这样),然后将生成器表达式传递给它:
If it is not to be a list but some other container class, as you mentioned in a comment on another answer, write that class to accept an iterable in its constructor (or, if it's not your code, subclass it to do so), then pass it a generator expression:
foo = MyContainer(sum(i, x) for i, x in enumerate(bar_list))
如果 foo
已经具有某些值,并且您希望添加新项目:
If foo
already has some value and you wish to append new items:
foo.extend(sum(i,x) for i, x in enumerate(bar_list))
如果您真的由于某种原因想要使用 append()
且又不想使用 for
循环,那么您可以使用此构造;生成器表达式将至少避免浪费您不想要的列表上的内存和CPU周期:
If you really want to use append()
and don't want to use a for
loop for some reason then you can use this construction; the generator expression will at least avoid wasting memory and CPU cycles on a list you don't want:
any(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
但是,这比常规的 for
循环还不清楚,并且仍然需要做一些额外的工作: any
正在测试的返回值每次迭代时foo.append()
.您可以编写一个使用迭代器并消除该检查的函数.最快的方法是使用零长度的 collections.deque
:
But this is a good deal less clear than a regular for
loop, and there's still some extra work being done: any
is testing the return value of foo.append()
on each iteration. You can write a function to consume the iterator and eliminate that check; the fastest way uses a zero-length collections.deque
:
from collections import deque
do = deque([], maxlen=0).extend
do(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
这实际上是很容易理解的,但是我相信它实际上没有比 any()
快得多,并且需要额外的导入.但是,如果担心的话, do()
或 any()
都比 for
循环快一点.
This is actually fairly readable, but I believe it's not actually any faster than any()
and requires an extra import. However, either do()
or any()
is a little faster than a for
loop, if that is a concern.
这篇关于什么时候删除列表理解和Python方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!