Python 创建单个列表项的列表乘以n次

Python 创建单个列表项的列表乘以n次,python,arrays,list,loops,emcee,Python,Arrays,List,Loops,Emcee,我对Python相当陌生,认为这应该是一个相当常见的问题,但找不到解决方案。我已经看过了,发现它对一个项目很有帮助,但我很难在不使用“for”循环的情况下将示例扩展到多个项目。我正在通过主持人为250名步行者运行这段代码,所以我正在寻找最快的方法 我有一个数字列表,a=[x,y,z]我想重复b=[1,2,3]次(例如),因此我最终得到了一个列表: [ [x], [y,y], [z,z,z] ] 我的“for”循环是: c = [ ] for i in range (0,len(a)):

我对Python相当陌生,认为这应该是一个相当常见的问题,但找不到解决方案。我已经看过了,发现它对一个项目很有帮助,但我很难在不使用“for”循环的情况下将示例扩展到多个项目。我正在通过主持人为250名步行者运行这段代码,所以我正在寻找最快的方法

我有一个数字列表,
a=[x,y,z]
我想重复
b=[1,2,3]
次(例如),因此我最终得到了一个列表:

[
 [x],
 [y,y],
 [z,z,z]
]
我的“for”循环是:

c = [ ]
for i in range (0,len(a)):
    c.append([a[i]]*b[i])

这正是我想要的,但意味着我的代码非常慢。我还天真地尝试将a和b转换为数组,并执行
[a]*b
,希望它能够逐元素相乘,但没有乐趣。

您可以使用
zip
和以下列表:

>>> a = ['x','y','z']
>>> b = [1,2,3]
>>> [[x]*y for x,y in zip(a,b)]
[['x'], ['y', 'y'], ['z', 'z', 'z']]
或:

zip
将首先在内存中创建整个列表,以使用
itertools.izip

如果
a
包含列表或列表等可变对象,则您可能必须在此处使用
copy.deepcopy
,因为修改一个副本也会更改其他副本:

>>> from copy import deepcopy as dc
>>> a = [[1 ,4],[2, 5],[3, 6, 9]]
>>> f = [[dc(x) for _ in xrange(y)] for x,y in zip(a,b)]

#now all objects are unique
>>> [[id(z) for z in x] for x in f]
[[172880236], [172880268, 172880364], [172880332, 172880492, 172880428]]
timeit
比较(忽略导入):


如果出于某种原因您不喜欢循环,这里有一个不带循环的版本:

map(lambda v: [v[0]]*v[1], zip(a,b))
我还要提醒您,此版本比列表理解稍慢:

$ a = ['hi']*100
$ b = [20]*100

$ %timeit map(lambda v: [v[0]]*v[1], zip(a,b))
10000 loops, best of 3: 101 us per loop

%timeit [[x]*y for x,y in zip(a,b)]
10000 loops, best of 3: 74.1 us per loop

如果您使用的是Python 2,我还建议您使用
itertools.izip
而不是
zip

@kirelagin建议使用一个没有
for
循环的版本,这里有一个也没有
lambda
的版本(请记住@AshwiniChaudhary的解决方案最具可读性)



创建一个
repeat
对象列表(如果您想要一个惰性迭代器而不是列表,请在Python 2.x上使用
imap
),这些对象不会占用内存中的任何额外空间,如果您只想对项目进行迭代而不是存储它们,这非常好)

最快的方法是使用和:

starmap
返回一个iterable,其中包含的值等于调用
repeat
的结果,参数等于元组中包含的值,在本例中,例如
('x',1)


我建议提及
itertools.izip
。谢谢!不过,“for”循环是否仍会降低代码的速度?@user2444731“slow”是什么意思?为什么您认为-for的
循环很慢?和什么相比慢?因为用户是新用户,所以指出[x]*y创建了对x的y引用可能是明智的,这在某些情况下可能会有问题。就好像一个被改变了一样,它们都有可能被改变。你可能应该提到,当你提出这个问题时,这是一个蒙特卡罗算法。上下文很有帮助。+1当你发布它时,我刚刚发现了这一点(但是输入不是列表列表)。请注意,你必须调用
starmap上的
map(list…)
来获取列表
map(lambda v: [v[0]]*v[1], zip(a,b))
$ a = ['hi']*100
$ b = [20]*100

$ %timeit map(lambda v: [v[0]]*v[1], zip(a,b))
10000 loops, best of 3: 101 us per loop

%timeit [[x]*y for x,y in zip(a,b)]
10000 loops, best of 3: 74.1 us per loop
>>> from itertools import repeat
>>> a = ['x','y','z']
>>> b = [1,2,3]
>>> map(list, map(repeat, a, b))
[['x'], ['y', 'y'], ['z', 'z', 'z']]
>>> map(repeat, a, b)
[repeat('x', 1), repeat('y', 2), repeat('z', 3)]
>>> from operator import mul
>>> map(mul, [['x'], ['y'], ['z']], [1, 2, 3])
[['x'], ['y', 'y'], ['z', 'z', 'z']]
>>> from itertools import repeat
>>> from itertools import starmap
>>> a = ['x','y','z']
>>> b = [1,2,3]
>>> starmap(repeat,zip(a,b))
>>> for p in starmap(repeat,zip(a,b)):
    print(list(p))


['x']
['y', 'y']
['z', 'z', 'z']