在列表中重复多次在另一个列表中指定的项目

dbl*_*iss 3 python list repeat

我有两个列表,x并且y:

>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

我想用这些来创建一个新列表.新列表将使每个元素x重复由相应元素指定的次数y.因此,期望的输出是

>>> new_list
[2, 3, 3, 4, 4, 4]
Run Code Online (Sandbox Code Playgroud)

元素的顺序new_list对我来说无关紧要.它也不是至关重要的list- 任何序列类型都可以.

实现这一目标的最快,最有效,最恐怖的方法是什么?

the*_*eye 9

  1. 你可以像这样使用列表理解

    >>> 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]
    
    Run Code Online (Sandbox Code Playgroud)

    在这里,我们zipxy使从元件x和其相应的计数y被归类为一个元组.然后,我们迭代count多个项目以生成相同的项目.

  2. 如果你的对象x是不可变的,那么你可以创建它们的count副本并将它们放在一个列表中,就像这样

    >>> [i for item, count in zip(x, y) for i in [item] * count]
    [2, 3, 3, 4, 4, 4]
    
    Run Code Online (Sandbox Code Playgroud)
  3. 你也可以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]
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,chain返回一个可迭代的,而不是一个列表.因此,如果您不想同时拥有所有元素,则可以逐个获取项目.如果它将是count一个非常大的数字,这将是高效的内存效率,因为我们不会立即在内存中创建整个列表.我们按需生成值.

  4. 谢谢ShadowRanger.实际上,你可以申请repeatxy而得到这样的结果

    >>> list(chain.from_iterable(map(repeat, x, y)))
    [2, 3, 3, 4, 4, 4]
    
    Run Code Online (Sandbox Code Playgroud)

    这里,map功能将应用中的值x,并yrepeat一个接一个.所以,结果map将是

    >>> list(map(repeat, x, y))
    [repeat(2, 1), repeat(3, 2), repeat(4, 3)]
    
    Run Code Online (Sandbox Code Playgroud)

    现在,我们使用chain.from_iterable从返回的iterable中的每个iterable中消耗值map.

  • `chain`方法可以简化为:`list(chain.from_iterable(map(repeat,x,y)))`(如果这是Py2,可能想要`from future_builtins import map`,在Py3上是不必要的). (4认同)

dbl*_*iss 6

numpy的repeat功能完成工作:

>>> import numpy as np
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
>>> np.repeat(x, y)
array([2, 3, 3, 4, 4, 4])
Run Code Online (Sandbox Code Playgroud)