我有
list = [a, b, c, d]
和
numbers = [2, 4, 3, 1]
我想获得一个类型列表:
new_list = [a, a, b, b, b, b, c, c, c, d]
这是我到目前为止所做的:
new_list=[]
for i in numbers:
for x in list:
for i in range(1,i+1):
new_list.append(x)
答案 0 :(得分:10)
以下是使用zip
,字符串乘法和列表理解进行此操作的一种方法:
lst = ['a', 'b', 'c', 'd']
numbers = [2 , 4, 3, 1]
r = [x for i, j in zip(lst, numbers) for x in i*j]
print(r)
# ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
使用Python时要注意名称的选择。像list
这样的名称会使内置列表函数无法使用。
如果lst
中的项目不是字符串,您只需在range
上使用嵌套理解就可以复制列表中的项目。
答案 1 :(得分:5)
嵌套列表理解有效:
L = ['a','b','c','d']
numbers = [2, 4, 3, 1]
>>> [x for x, number in zip(L, numbers) for _ in range(number)]
['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
"子循环" for _ in range(number)
重复number
次值。
这里L
可以保存任何对象,而不仅仅是字符串。
示例:
L = [[1, 2, 3],'b','c', 'd']
numbers = [2, 4, 3, 1]
[x for x, number in zip(L, numbers) for _ in range(number)]
[[1, 2, 3], [1, 2, 3], 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
但这会使子列表变平:
[x for i, j in zip(L, numbers) for x in i*j]
[1, 2, 3, 1, 2, 3, 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
不完全是理想的结果。
答案 2 :(得分:4)
作为任何对象(不仅仅是字符串)的一般方法,您可以在生成器表达式中使用itertools.repeat()
:
def repeat_it(lst, numbers):
return chain.from_iterable(repeat(i, j) for i, j in zip(lst, numbers))
演示:
In [13]: from itertools import repeat, chain
In [21]: lst=[5,4,6,0]
In [22]: list(repeat_it(lst, numbers))
Out[22]: [5, 5, 4, 4, 4, 4, 6, 6, 6, 0]
In [23]: lst=['a','b','c','d']
In [24]: list(repeat_it(lst, numbers))
Out[24]: ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
以下是3种主要方法的基准。请注意,最后一个onley适用于字符串:
In [49]: lst = lst * 1000
In [50]: numbers = numbers * 1000
In [51]: %timeit list(chain.from_iterable(repeat(i, j) for i, j in zip(lst, numbers)))
1 loops, best of 3: 8.8 s per loop
In [52]: %timeit [x for x, number in zip(lst, numbers) for _ in range(number)]
1 loops, best of 3: 12.4 s per loop
In [53]: %timeit [x for i, j in zip(lst, numbers) for x in i*j]
1 loops, best of 3: 7.2 s per loop
答案 3 :(得分:2)
您可以使用numpy.repeat()
作为另一种选择:
import numpy as np
np.repeat(lst, numbers).tolist()
# ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
答案 4 :(得分:1)
使用循环执行此操作的另一种方法是:
new_list = []
for number, item in zip(numbers, l):
for i in range(number):
new_list.append(item)
现在我们有:
new_list = ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
答案 5 :(得分:1)
如果您不确定列表推导是如何工作的,
myList=['a','b','c','d'] # not a good idea to use list as a name for your variable
numbers=[2,4,3,1]
new_list=[]
for i in range(len(myList)):
for j in range(numbers[i]):
new_list.append(myList[i])
print(new_list)
答案 6 :(得分:1)
无论a,b,c和d是变量还是字符串,这都会起作用:
a = 1
b = 2.0
c = "cheese"
d = ["c", "a", "k", "e"]
lst = [a, b, c, d]
numbers = [2, 4, 3, 1]
# if len(lst) == len(numbers):
new_lst = [i for i, j in zip(lst, numbers) for k in range(j)]
您可能想要取消注释if语句(并缩进下面的行)以检查列表是否具有相同的长度,否则new_lst将只包含与较短列表一样多的项目。
This,this和the documentation section on nested list comprehensions值得一读。
答案 7 :(得分:1)
这是我的解决方案,只是为了添加另一个。
l = ['a', 'b', 'c', 'd']
n = [2, 4, 3, 1]
r = []
for i,v in enumerate(l):
r += list(v*n[i])
>>> r
['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd']
答案 8 :(得分:0)
假设两个列表长度相同而第二个列表始终是数字列表,这里是一个不使用zip
或任何导入的解决方案:
lst = ['a', 'b', 'c', 'd']
numbers = [2,4,3,1]
result = sum([[lst[i]]*numbers[i] for i in range(len(lst))],[])