簡體   English   中英

具有重復連續數字的范圍

[英]Range with repeated consecutive numbers

我想創建一個范圍(例如 (1, 5))的數字,並帶有一些重復(例如 4):

[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]

一種方法是寫:

list(itertools.chain(*([x] * 4 for x in range(1, 5))))

或者類似的:

list(itertools.chain(*(itertools.repeat(x, 4) for x in range(1, 5))))

然而,有一個平坦化的步驟,這是可以避免的。

是否有更pythonic或更緊湊的版本來生成這樣的序列?

您可以改為使用列表理解

l = [i for i in range(1, 5) for _ in range(4)]

輸出

[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]

您的解決方案沒有任何問題。 但是您可以使用chain.from_iterable來避免解包步驟。

否則,我唯一的其他推薦是 NumPy,如果您願意使用 3rd 方庫。

from itertools import chain, repeat
import numpy as np

# list solution
res = list(chain.from_iterable(repeat(i, 4) for i in range(1, 5)))

# NumPy solution
arr = np.repeat(np.arange(1, 5), 4)

嘗試這個,

range(1,5)*4 # if you don't consider order
sorted(range(1,5)*4) # for ordered seq

隨着性能更新

Mihai Alexandru-Ionut 答案:

%timeit [i for i in range(1, 5) for _ in range(4)]

1000000 loops, best of 3: 1.91 µs per loop

jpp 回復:

%timeit list(chain.from_iterable(repeat(i, 4) for i in range(1, 5)))

100000 loops, best of 3: 2.12 µs per loop

%timeit np.repeat(np.arange(1, 5), 4)

1000000 loops, best of 3: 1.68 µs per loop

羅里·道爾頓回答:

%timeit [n for n in range(1,5) for repeat in range(4)]

1000000 loops, best of 3: 1.9 µs per loop

傑沃德回答:

%timeit list(i//4 for i in range(1*4, 5*4))

100000 loops, best of 3: 2.47 µs per loop

RoadRunner 評論區推薦:

%timeit for i in range(1, 5): lst.extend([i] * 4)

1000000 loops, best of 3: 1.46 µs per loop

我的答案:

%timeit sorted(range(1,5)*4)

1000000 loops, best of 3: 1.3 µs per loop

我認為chain + repeat可能是你最好的選擇。 話雖如此,

start = 1
stop = 5
repeat = 4

x = list(i//repeat for i in range(start*repeat, stop*repeat))

print(x)

應該有效(至少對於正參數)。

我非常喜歡簡單易懂的代碼。 有了這種哲學,我會用

[n for n in range(1,5) for repeat in range(4)]

我只想提一下, extend也可能是一種選擇。 也許不如單行列表理解那么漂亮,但是當buckets的大小增加時它會表現得更好

def listExtend():
    a = []
    for i in range(1,5):
        a.extend([i]*4)
    return a


def listComprehension():
    return [[i,x] for i in range(1, 5) for x in range(4)]


import timeit
print(timeit.timeit(stmt="listComprehension()", setup="from __main__ import listComprehension", number=10**7))
print(timeit.timeit(stmt="listExtend()", setup="from __main__ import listExtend", number=10**7))
14.2532608
8.78004566

一種選擇,雖然它需要安裝一個包,但它是itertation_utilities.replicate

>>> from iteration_utilities import replicate
>>> list(replicate(range(1, 5), 4))
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]

如果你不想安裝那個包, replicate函數本質上等同於這個函數:

from itertools import repeat

def replicate(items, repeats):
    for item in items:
        for _ in repeat(None, repeats):
            yield item

以防萬一您對性能感興趣,我為幾個(不是全部)提議的替代方案做了一些微基准測試:

在此處輸入圖片說明

如您所見,NumPy 和iteration_utilities方法最快,而所有其他方法的速度大致相同。

有趣的是,在這些其他方法中, list.extend方法最快,(我的)自定義生成器最慢。 我沒想到。

這是復制基准的代碼:

from iteration_utilities import replicate
from itertools import chain, repeat
import numpy as np

def replicate_generator_impl(upper):
    for item in range(1, upper):
        for _ in repeat(None, 4):
            yield item

def replicate_generator(upper):
    return list(replicate_generator_impl(upper))

def iteration_utilities_replicate(upper):
    return list(replicate(range(1, upper), 4))

def double_comprehension(upper):
    return [i for i in range(1, upper) for _ in range(4)]

def itertools_chain(upper):
    return list(chain(*([x] * 4 for x in range(1, upper))))

def itertools_chain_from_iterable(upper):
    return list(chain.from_iterable(repeat(i, 4) for i in range(1, upper)))

def extend(upper):
    a = []
    for i in range(1, upper):
        a.extend([i] * 4)
    return a

def numpy_repeat(upper):
    return np.repeat(np.arange(1, upper), 4)

from simple_benchmark import benchmark

funcs = [replicate_generator, iteration_utilities_replicate, double_comprehension, itertools_chain, itertools_chain_from_iterable, extend, numpy_repeat]
arguments = {2**i: 2**i for i in range(1, 15)}
b = benchmark(funcs, arguments, argument_name='size')
b.plot()

如果您想知道沒有 NumPy 方法會是什么樣子:

在此處輸入圖片說明


免責聲明:我是iteration_utilitiessimple_benchmark的作者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM