Create duplicates in the list
我有
1 | list = [a, b, c, d] |
和
1 | numbers = [2, 4, 3, 1] |
号
我想得到一个以下类型的列表:
1 | new_list = [a, a, b, b, b, b, c, c, c, d] |
这就是我目前为止所拥有的:
1 2 3 4 5 | new_list=[] for i in numbers: for x in list: for i in range(1,i+1): new_list.append(x) |
。
有一种方法可以使用
1 2 3 4 5 6 | 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时要注意名称的选择。像
如果
嵌套列表理解工作:
1 2 3 4 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'] |
"子循环"
例子:
1 2 3 4 | 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'] |
。
但这会使子列表变平:
1 2 | [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'] |
不完全是期望的结果。
作为任何对象(不仅是字符串)的一般方法,可以在生成器表达式中使用
1 2 | def repeat_it(lst, numbers): return chain.from_iterable(repeat(i, j) for i, j in zip(lst, numbers)) |
。
演示:
1 2 3 4 5 6 7 8 9 10 11 | 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种主要方法的基准。请注意,最后一个选项仅适用于字符串:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
您可以使用
1 2 3 4 | import numpy as np np.repeat(lst, numbers).tolist() # ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] |
号
这是我的解决方案,只是添加一个不同的。
1 2 3 4 5 6 7 8 | 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'] |
号
无论a、b、c和d是变量还是字符串,这都可以工作:
1 2 3 4 5 6 7 8 9 10 | 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语句的注释(并缩进下面的行),以检查列表是否具有相同的长度,否则,新的清单将只包含与较短清单相同的项目。
这个、这个和关于嵌套列表理解的文档部分是值得阅读的。
如果你不确定列表理解是如何工作的,
1 2 3 4 5 6 7 8 | 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) |
。
另一种处理循环的方法是:
1 2 3 4 | new_list = [] for number, item in zip(numbers, l): for i in range(number): new_list.append(item) |
。
现在我们有:
1 | new_list = ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] |
假设两个列表的长度相同,第二个列表总是一个数字列表,这里有一个不使用
1 2 3 4 | lst = ['a', 'b', 'c', 'd'] numbers = [2,4,3,1] result = sum([[lst[i]]*numbers[i] for i in range(len(lst))],[]) |
号