3

我创建了一行,以下列方式将对象附加到列表中

>>> 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 列表来附加值,因此我不需要将列表理解行分配给某些东西。

我的问题更多是关于编程正确性的问题

我应该放弃列表理解而只使用简单的 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
4

3 回答 3

8

是的,这是不好的风格。列表推导是建立一个列表。您正在构建一个充满Nones 的列表,然后将其丢弃。您实际想要的结果是这种努力的副作用。

为什么不foo首先使用列表推导来定义?

foo = [sum(i,x) for i, x in enumerate(bar_list)]

如果它不是一个列表而是某个其他容器类,正如您在另一个答案的评论中提到的那样,请编写该类以在其构造函数中接受一个可迭代对象(或者,如果它不是您的代码,则对其进行子类化),然后传递给它一个生成器表达式:

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()不想使用循环,那么您可以使用这种结构;生成器表达式至少可以避免在您不想要的列表上浪费内存和 CPU 周期:for

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

于 2013-07-30T20:58:03.500 回答
7

我认为通常不赞成仅将列表推导用于副作用,所以我会说在这种情况下使用 for 循环更好。

但无论如何,你不能这样做foo = [sum(i,x) for i, x in enumerate(bar_list)]吗?

于 2013-07-30T20:56:24.260 回答
3

绝对应该放弃列表理解。结束。

  • 你让任何阅读你的代码的人感到困惑。您正在建立一个副作用列表。
  • 您正在为构建您再次丢弃的列表支付 CPU 周期和内存。

在您的简化情况下,您忽略了可以直接使用列表推导的事实:

[sum(i,x) for i, x in enumerate(bar_list)]
于 2013-07-30T20:57:10.370 回答