问题:创建重复N次的单个项目的列表
我想创建一系列长度不一的列表。每个列表将包含相同的元素e
,重复n
次数(其中n
=列表的长度)。
如何创建列表,而不[e for number in xrange(n)]
对每个列表使用列表理解?
回答 0
您还可以编写:
[e] * n
您应该注意,例如,如果e是一个空列表,您将得到一个具有n个指向同一列表的引用的列表,而不是n个独立的空列表。
性能测试
乍看之下,似乎是重复是创建一个具有n个相同的元素列表的最快方法:
>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819
但是等等-这不是一个公平的测试…
>>> itertools.repeat(0, 10)
repeat(0, 10) # Not a list!!!
该函数itertools.repeat
实际上并没有创建列表,它只是创建一个对象,您可以根据需要使用该对象来创建列表!让我们再试一次,但转换为列表:
>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233
因此,如果您想要列表,请使用[e] * n
。如果要延迟生成元素,请使用repeat
。
回答 1
>>> [5] * 4
[5, 5, 5, 5]
当重复的项目是列表时,请当心。该列表将不会被克隆:所有元素都将引用同一列表!
>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]
回答 2
在Python中创建重复n次的单项列表
不变物品
对于不可变的项目,例如“无”,布尔值,整数,浮点数,字符串,元组或Frozensets,可以这样进行:
[e] * 4
请注意,这最好仅与列表中的不可变项(字符串,元组,frozensets)一起使用,因为它们都指向内存中同一位置的同一项。当我必须构建一个包含所有字符串的架构的表时,我会经常使用它,这样就不必提供高度冗余的一对一映射。
schema = ['string'] * len(columns)
可变项
我已经使用Python很长时间了,而且从未见过用可变实例执行上述操作的用例。相反,要获取可变的空列表,集合或字典,您应该执行以下操作:
list_of_lists = [[] for _ in columns]
在这种情况下,下划线只是一个简单的变量名。
如果只有号码,那将是:
list_of_lists = [[] for _ in range(4)]
该_
不是真的很特别,但你的编码环境风格检查可能会抱怨,如果你不打算使用的变量和使用的其他任何名称。
对可变项使用不可变方法的注意事项:
当心使用可变对象,当您更改其中一个对象时,它们都会更改,因为它们都是同一对象:
foo = [[]] * 4
foo[0].append('x')
foo现在返回:
[['x'], ['x'], ['x'], ['x']]
但是对于不可变的对象,您可以使其起作用,因为您可以更改引用,而不是对象:
>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]
>>> l = [frozenset()] * 4
>>> l[0] |= set('abc')
>>> l
[frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]
但同样,可变对象对此没有好处,因为就地操作会更改对象,而不是引用:
l = [set()] * 4
>>> l[0] |= set('abc')
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]
回答 3
Itertools具有此功能:
import itertools
it = itertools.repeat(e,n)
当然可以itertools
为您提供迭代器,而不是列表。[e] * n
为您提供了一个列表,但是根据您对这些序列的处理方式,itertools
变体可能会更加有效。
回答 4
正如其他人指出的那样,对可变对象使用*运算符会重复引用,因此,如果更改一个,则会全部更改。如果要创建可变对象的独立实例,则xrange语法是执行此操作的最Python方式。如果您有一个从未使用过的命名变量而感到困扰,则可以使用匿名下划线变量。
[e for _ in xrange(n)]
回答 5
[e] * n
应该管用