65

R 函数 rep() 复制向量的每个元素:

> rep(c("A","B"), times=2)
[1] "A" "B" "A" "B"

这就像 Python 中的列表乘法:

>>> ["A","B"]*2
['A', 'B', 'A', 'B']

但是使用 rep() R 函数也可以为向量的每个元素指定重复次数:

> rep(c("A","B"), times=c(2,3))
[1] "A" "A" "B" "B" "B"

Python中有这样的功能吗?不然怎么定义呢?顺便说一句,我也对这种用于复制数组行的函数感兴趣。

4

8 回答 8

70

使用numpy数组和numpy.repeat函数:

import numpy as np

x = np.array(["A", "B"])
print np.repeat(x, [2, 3], axis=0)

['A' 'A' 'B' 'B' 'B']
于 2012-09-02T11:34:44.047 回答
10

不确定是否有可用的内置功能,但您可以尝试以下操作:

>>> lis = ["A", "B"]
>>> times = (2, 3)
>>> sum(([x]*y for x,y in zip(lis, times)),[])
['A', 'A', 'B', 'B', 'B']

请注意,sum()以二次时间运行。所以,这不是推荐的方式。

>>> from itertools import chain, izip, starmap
>>> from operator import mul
>>> list(chain.from_iterable(starmap(mul, izip(lis, times))))
['A', 'A', 'B', 'B', 'B']

时序对比:

>>> lis = ["A", "B"] * 1000
>>> times = (2, 3) * 1000
>>> %timeit list(chain.from_iterable(starmap(mul, izip(lis, times))))
1000 loops, best of 3: 713 µs per loop
>>> %timeit sum(([x]*y for x,y in zip(lis, times)),[])
100 loops, best of 3: 15.4 ms per loop
于 2012-09-02T11:31:59.617 回答
5

既然你说“数组”并提到 R。你可能无论如何都想使用 numpy 数组,然后使用:

import numpy as np
np.repeat(np.array([1,2]), [2,3])

编辑:既然你提到你也想重复行,我认为你应该使用 numpy. np.repeat有一个轴参数来做到这一点。

除此之外,也许:

from itertools import izip, chain, repeat
list(chain(*(repeat(a,b) for a, b in izip([1,2], [2,3]))))

因为它没有假设您有一个列表或字符串要相乘。尽管我承认,将所有内容作为参数传递到链中可能并不完美,因此编写自己的迭代器可能会更好。

于 2012-09-02T11:37:02.967 回答
3
l = ['A','B']
n = [2, 4]

您的示例使用已经是可迭代的字符串。您可以生成类似于列表的结果字符串。

''.join([e * m for e, m in zip(l, n)])
'AABBBB'

更新:这里不需要列表理解:

''.join(e * m for e, m in zip(l, n))
'AABBBB'
于 2012-09-02T11:33:22.157 回答
3

你怎么看这种方式?

重复一个值:

>>> repetitions=[]
>>> torep=3
>>> nrep=5
>>> for i in range(nrep):
>>>     i=torep
>>>     repetitions.append(i)
[3, 3, 3, 3, 3]

重复一个序列:

>>> repetitions=[]
>>> torep=[1,2,3,4]
>>> nrep= 2
>>> for i in range(nrep):
>>>     repetitions=repetitions+torep
>>> print(repetitions)
[1, 2, 3, 4, 1, 2, 3, 4]
于 2019-02-01T16:33:43.140 回答
0

以下可能对您有用:

>>>[['a','b'],['A','B']]*5


[['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B']]
于 2020-10-13T09:00:29.663 回答
0

numpy.repeat已经提到过,这显然等同于您想要的。但为了完整起见,标准库中也repeat有。itertools但是,这通常适用于可迭代对象,因此它不允许按索引重复(因为可迭代对象通常没有定义索引)。

我们可以使用那里给出的代码作为粗略的等价物

def repeat(object, times=None):
    # repeat(10, 3) --> 10 10 10
    if times is None:
        while True:
            yield object
    else:
        for i in xrange(times):
            yield object

定义我们自己的广义重复:

def repeat_generalised(object, times=None):
    # repeat(10, 3) --> 10 10 10
    if times is None:
        while True:
            yield object
    else:
        for reps, elem in zip(times, object):
            for i in xrange(reps): 
                yield elem

问题当然是你必须定义很多可能的边缘情况(如果对象和时间有不同数量的元素会发生什么?),这取决于你个人的用例。

于 2020-10-13T09:28:48.023 回答
0

这是我对克隆的尝试R rep

def rep(x, times = 1, each = 1, length_out = None):
    if not isinstance(times, list):
        times = [times]

    res = ''.join([str(i) * each for i in x])

    if len(times) > 1:   
        res = ''.join(str(i) * m for i, m in zip(x, times))
    else:
        res = ''.join(res * times[0])
    
    if length_out is None:
        return res
    else:
        return res[0:length_out]

重现R示例:

rep(range(4), times = 2)
rep(range(4), each = 2)
rep(range(4), times = [2,2,2,2])
rep(range(4), each = 2, length_out = 4)
rep(range(4), each = 2, times = 3)

除了没有回收较短的向量/列表(imo这是最糟糕的功能R)。

于 2020-12-02T17:14:43.180 回答