繁体   English   中英

用于在列表中创建给定数量元素的 Python 习惯用法

[英]Python idiom for creating a given number of elements in a list

通常,当我使用 Python 时,我会发现自己编写的列表推导式看起来像这样:

num_foobars = 10
foobars = [create_foobar() for idx in xrange(num_foobars)]

显然这工作得很好,但是当我实际上根本没有使用该信息时,创建一个范围并在其中迭代虚拟索引对我来说仍然感觉有点尴尬。

我一点也不关心性能或类似的东西,只是感觉不像 Python 通常那样优雅。

我想知道是否有任何很好的惯用方法来避免不必要的列表理解语法,也许使用mapitertools类的东西,给我看起来更像的代码......

num_foobars = 10
foobars = repeat(create_foobar, num_foobars)

这是 itertools 方式:

list(starmap(create_foobar, repeat((), 10)))

itertools 的方式又短又快。 也就是说,我更喜欢列表理解:-)

create_foobar接受参数的情况下,它只是迭代参数列表的问题。

[create_foobar(x) for x in arg_list]

要么

[create_foobar(*x) for x in [arg_tuple] * 10]

但是在create_foobar没有参数的特殊情况下,我想你可以这样做:

>>> class Foobar(object):
...     def __init__(self):
...         self.a = random.randrange(0, 10)
...     def __repr__(self):
...         return str(self.a)
... 
>>> map(lambda x: x(), [Foobar] * 10)
[2, 5, 3, 4, 7, 4, 6, 3, 3, 6]

不过 lambda 有点难看; Raymond Hettinger的观点相呼应,我认为标准列表理解更可取。 还值得注意的是,这会创建一个相当长且无用的列表来迭代,这是标准方法避免的。 您可以通过使用itertools.repeat创建一个可迭代的Foobar来解决这个问题……增加了更多的复杂性。

>>> map(lambda x: x(), itertools.repeat(Foobar, 10))
[1, 4, 4, 6, 2, 4, 9, 9, 1, 6]

更一般地,考虑一下:如果你不遍历任何东西,必须有一个索引变量,即使它是隐藏的; 显式优于隐式。

您可以定义函数repeat ,但编写它的惯用方法仍然是

def repeat(f, max_n):
    return [f(i) for i in xrange(max_n)]

对于那个很抱歉。 我同意基于xrange的构造通常看起来很难看,但这正是语言的工作原理。

def repeat(creator, num):
    return [create() for x in xrange(num)]

;C)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM