диапазон python () с дубликатами? - PullRequest
5 голосов
/ 25 августа 2011

Так что все знают, что я могу получить список чисел с range примерно так:

>>> range(5)
[0, 1, 2, 3, 4]

И если я хочу, скажем, 3 копии каждого числа, которое я мог бы использовать:

>>> range(5)*3
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]

Но есть ли способ использовать range для повторения подобных копий вместо этого?

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

Существует ли быстрый и элегантный встроенный способ сделать это?sorted(range(5)*3) имеет ненужную сложность n * log (n), а [x//3 for x in range(3*5)] работает, но выглядит как злоупотребление // операцией.

Ответы [ 8 ]

14 голосов
/ 25 августа 2011

Вы можете сделать:

>>> [i for i in range(5) for _ in range(3)]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]

часть range(3) должна быть заменена вашим количеством повторений ...

Кстати, вы должны использовать генераторы


Чтобы было понятнее, _ - это имя переменной для чего-то, что вас не волнует (любое имя разрешено).

Это понимание списка использует вложенные циклы for и выглядит так:

for i in range(5):
    for j in range(3):
        #your code here
7 голосов
/ 25 августа 2011

Попробуйте это:

itertools.chain.from_iterable(itertools.repeat(x, 3) for x in range(5))
4 голосов
/ 25 августа 2011
from itertools import chain, izip
list(chain(*izip(*[xrange(5)]*3)))

Придает

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

Выйдите из списка, и у вас будет генератор.

РЕДАКТИРОВАТЬ: или даже лучше (пропускает вызов функции в izip):

list(chain(*([x]*3 for x in xrange(5))))
1 голос
/ 26 августа 2011

Крутой итератор, использующий другой подход:

>>> from collections import Counter
>>> Counter(range(5) * 3).elements()
1 голос
/ 26 августа 2011
>>> from itertools import chain, izip, tee
>>> list(chain.from_iterable(izip(*tee(range(5), 3))))
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
0 голосов
/ 07 августа 2018

Существует очень простой способ сделать это с помощью numpy .Пример:

>>> import numpy as np
>>> np.arange(5*3) // 3
array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])

С range вы можете сделать следующее:

>>> list(map(lambda x: x // 3, range(5*3)))
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]

Помня, что // выполняет строго целочисленное деление.

0 голосов
/ 25 августа 2011

Мне нравится, чтобы все было просто:)

>>> sorted(list(range(5)) * 3)
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
0 голосов
/ 25 августа 2011
import itertools
[x for tupl in itertools.izip(*itertools.tee(range(0,5),3)) for x in tupl]

Или:

[x for tupl in zip(range(0,5), range(0,5), range(0,5)) for x in tupl]
...