我创建了一行,以下列方式将对象附加到列表
>>> 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 Expression is assigned to nothing,但因为我已经在使用 foo 列表来附加值,所以我不需要将 List Comprehension 行赋值给某些东西。
我的问题更多是关于编程正确性的问题
我应该放弃列表理解并只使用简单的 for 表达式吗?
>>> for i, x in enumerate(bar_list):
... foo.append(sum(i,x))
或者是否有一种正确的方法来同时使用列表推导式和不赋值?
回答
谢谢@user2387370、@kindall 和@Martijn Pieters。对于其余的注释,我使用 append,因为我没有使用 list(),我没有使用 i+x,因为这只是一个简化的示例。
我将其保留如下:
histogramsCtr = hist_impl.HistogramsContainer()
for index, tupl in enumerate(local_ranges_per_histogram_list):
histogramsCtr.append(doSubHistogramData(index, tupl))
return histogramsCtr
最佳答案
是的,这是糟糕的风格。列表理解是建立一个列表。您正在构建一个充满 None
的列表,然后将其丢弃。您实际期望的结果是这项工作的副作用。
为什么不首先使用列表理解来定义 foo
?
foo = [sum(i,x) for i, x in enumerate(bar_list)]
如果它不是一个列表而是其他一些容器类,正如您在另一个答案的评论中提到的那样,编写该类以在其构造函数中接受一个可迭代对象(或者,如果这不是您的代码,则将其子类化以执行so), 然后传递给它一个生成器表达式:
foo = MyContainer(sum(i, x) for i, x in enumerate(bar_list))
如果 foo
已经有一些值并且您希望追加新项目:
foo.extend(sum(i,x) for i, x in enumerate(bar_list))
如果您真的想要使用append()
并且出于某种原因不想使用for
循环,那么您可以使用这个结构;生成器表达式至少会避免在您不想要的列表上浪费内存和 CPU 周期:
any(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
但这比常规的 for
循环要清晰得多,而且还有一些额外的工作要做:any
正在测试 的返回值foo.append()
在每次迭代中。您可以编写一个函数来使用迭代器并消除该检查;最快的方法是使用零长度 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
循环快一点,如果这是一个问题的话。
关于python - 什么时候删除列表理解和 Pythonic 方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17957181/