Python, как перетасовать упорядоченный список, чтобы создать последовательность элементов?

Например, у нас есть упорядоченный список:

a = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]

Я хочу перетасовать этот массив, чтобы сформировать:

a = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]

В настоящее время я делаю:

a = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
n_unique_elements = 4
arrays_with_same_elements = np.array_split(a, 5)

for idx in range(n_unique_elements):
    final_list.append(list_similar_a[0][idx])
    final_list.append(list_similar_a[1][idx])
    final_list.append(list_similar_a[2][idx])
    final_list.append(list_similar_a[3][idx])
    final_list.append(list_similar_a[4][idx])

Итак, переменная

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

Должен быть pythonic способ сделать это. Возможно, встроенная функция в numpy? Какие еще методы приходят вам на ум для решения этой проблемы?

как насчет np.random.shuffle(a). (Честно говоря, это первый результат, если вы ищете «перетасовку списка python»...)

Magellan88 23.06.2019 18:33

@Magellan88 np.random.shuffle(a) не сохраняет порядок элементов в последовательности. Мне нужно, чтобы новый массив был [1, 2, 3, 1, 2, 3, ...]

PPrasai 23.06.2019 18:37

Всегда ли количество вхождений каждого элемента одинаково?

GZ0 23.06.2019 18:39

@ GZ0 Да. Частота каждого уникального элемента одинакова.

PPrasai 23.06.2019 18:40

Частота известна заранее или ее нужно вычислять по списку?

GZ0 23.06.2019 18:41

@GZ0 они известны заранее

PPrasai 23.06.2019 18:42
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
56
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Вы можете использовать ключевой параметр в методе sort(): https://docs.python.org/3.3/howto/sorting.html#key-функции или используя набор()

a = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
b = set(a)
final_list = list(b) * len(b)

Это очень умно! Спасибо.

PPrasai 23.06.2019 18:38

Попробуйте: (чистый питон без внешней библиотеки)

STEP = 3
lst0 = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
lst1 = []

for x in range(0, STEP):
    for y in range(0, len(lst0), STEP):
        lst1.append(lst0[y + x])
print(lst1)

выход

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

Итак, вы можете использовать numpy:

a.reshape([4,3]).T.flatten()

поэтому .reshape() помещает его в прямоугольную матрицу, .T переключает строки и столбцы, а .flatten() снова помещает его в линейный вектор

теперь вам нужно только придумать параметры для части изменения формы, например. .reshape([step, repetition])

Вау, это действительно классная техника. Спасибо за объяснение ответа.

PPrasai 23.06.2019 18:43

да, и извините за непонимание вашего вопроса сначала... мой плохой

Magellan88 23.06.2019 18:45

Если частота каждого элемента одинакова и известна заранее, это решение также будет работать.

FREQ = 3
output = a[::FREQ] * (len(a) // FREQ)

Еще одно решение на основе numpy:

FREQ = 3
output = a.reshape((-1, FREQ)).flatten(order='F')

Аргумент order='F' выравнивает матрицу по столбцам.

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

    a = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
    uniqueValues, occurCount = np.unique(a, return_counts=True) # uniqueValues is the array of unique elements of main list
                                                                #occurCount is array containing frequency of unique elements
    common_occur=min(occurCount)                                # get frequency of co-occurrance

    final_array=np.tile(uniqueValues,common_occur)              #get tiled output array

Другие вопросы по теме