什么时候删除列表理解和Python方式? [英] When to drop list Comprehension and the Pythonic way?

查看:65
本文介绍了什么时候删除列表理解和Python方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一条以以下方式将对象追加到列表的行

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

如果不是列表而是其他容器类,如您在另一个答案的注释中所述,请编写该类以在其构造函数中接受一个I​​terable(或者,如果不是您的代码,请将该类子类化)这样),然后将生成器表达式传递给它:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆