我有两个列表,x
和y
:
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
我想用这些来创建一个新列表。新列表将使x
中的每个元素重复y
中相应元素指定的次数。因此,期望的输出是
>>> new_list
[2, 3, 3, 4, 4, 4]
new_list
中元素的顺序对我来说无关紧要。它是list
并不重要 - 任何序列类型都可以。
实现这一目标的最快,最有效,最恐怖的方式是什么?
答案 0 :(得分:8)
您可以使用列表推导,就像这样
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
>>> [item for item, count in zip(x, y) for i in range(count)]
[2, 3, 3, 4, 4, 4]
在这里,我们zip
x
和y
,以便x
中的元素及其y
的相应计数被分组为单个元组。然后,我们迭代count
个项目以生成相同的项目。
如果x
中的对象是不可变的,那么您可以创建相同的count
个副本并将它们放在一个列表中,如下所示
>>> [i for item, count in zip(x, y) for i in [item] * count]
[2, 3, 3, 4, 4, 4]
您可以使用itertools.repeat
懒惰地执行此操作,就像这样
>>> from itertools import chain, repeat
>>> chain.from_iterable((repeat(item, count) for item, count in zip(x,y)))
<itertools.chain object at 0x7fabe40b5320>
>>> list(chain.from_iterable((repeat(item, cnt) for item, cnt in zip(x,y))))
[2, 3, 3, 4, 4, 4]
请注意chain
返回一个可迭代的,而不是一个列表。因此,如果您不想一次想要所有元素,您可以逐一获取这些项目。如果count
将是一个非常大的数字,这将是高内存效率,因为我们不会立即在内存中创建整个列表。我们按需生成值。
Thanks ShadowRanger。您实际上可以将repeat
应用于x
和y
并获得此结果
>>> list(chain.from_iterable(map(repeat, x, y)))
[2, 3, 3, 4, 4, 4]
此处,map
函数会逐一将x
和y
的值应用于repeat
。因此,map
的结果将是
>>> list(map(repeat, x, y))
[repeat(2, 1), repeat(3, 2), repeat(4, 3)]
现在,我们使用chain.from_iterable
来消耗map
返回的每个可迭代值中的值。
答案 1 :(得分:5)
>>> import numpy as np
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
>>> np.repeat(x, y)
array([2, 3, 3, 4, 4, 4])
函数可以完成工作:
//TITLE/SUBTITLE//PART[SECTION/SECTNO[text() = '§ 400.1']]
//TITLE/SUBTITLE//PART[SUBPART/SECTION/SECTNO[text() = '§ 415.1']]
答案 2 :(得分:0)
使用for
循环简单。
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
>>> final = []
>>> for index, item in enumerate(y):
final.extend([x[index]]*item)
答案 3 :(得分:0)
实现此目标的一种方法是使用.elements()
的collections.Counter()
函数和zip
。例如:
>>> from collections import Counter
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
# `.elements()` returns an object of `itertool.chain` type, which is an iterator.
# in order to display it's content, here type-casting it to `list`
>>> list(Counter(dict(zip(x,y))).elements())
[2, 3, 3, 4, 4, 4]