Каков наилучший способ разделить список на примерно равные части? Например, если список состоит из 7 элементов и разделен на 2 части, мы хотим получить 3 элемента в одной части, а другая должна содержать 4 элемента.
Я ищу что-то подобное even_split(L, n)
, разбивается L
на n
части.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in range(0, len(L), n):
yield L[i:i+n]
Код выше дает 3 порции, а не 3 порции. Я мог бы просто переставить (перебрать это и взять первый элемент каждого столбца, вызвать эту часть первую, затем взять второй и поместить его во вторую часть и т. Д.), Но это разрушает порядок элементов.
>>> chunkIt(range(8), 6)
=>[[0], [1], [2, 3], [4], [5], [6], [7]]
chunkIt(range(10), 9)
должен вернуть 9 частей, но это не так.Вы можете написать это довольно просто как генератор списков:
Пример:
источник
n = min(n, len(a)) # don't create empty buckets
в строку 1, чтобы избежать создания пустых сегментов в таких сценариях, какlist(split(range(X, Y)))
гдеX < Y
Это смысл для
numpy.array_split
*:* кредит Зеро Пирей в комнате 6
источник
*
вprint
течение?print(L)
и `напечатайте (* L). Также см. Stackoverflow.com/a/36908/2184122 или поиск "использование звездочкой Python".Пока вы не хотите ничего глупого, как непрерывные куски:
источник
zip(*chunkify(range(13), 3))
результаты[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
Изменение кода для получения
n
кусков, а не кусковn
:который дает:
Это назначит дополнительные элементы для последней группы, которая не является идеальной, но вполне соответствует вашей спецификации «примерно N равных частей» :-) Под этим я подразумеваю, что 56 элементов будут лучше, чем (19,19,18), тогда как это дает (18,18,20).
Вы можете получить более сбалансированный вывод с помощью следующего кода:
какие выводы:
источник
for x in chunks(mylist,num): print x
, я получаю нужные куски, но между ними я получаю пустой список. Есть идеи почему? То есть я получаю много[]
, по одному за каждый кусок.Если вы разделите
n
элементы примерно наk
куски, вы можете сделатьn % k
блок на 1 элемент больше, чем другие куски, чтобы распределить дополнительные элементы.Следующий код даст вам длину кусков:
Пример:
n=11, k=3
результаты в[4, 4, 3]
Затем вы можете легко рассчитать начальные индексы для кусков:
Пример:
n=11, k=3
результаты в[0, 4, 8]
Используя
i+1
й кусок в качестве границы мы получаем , чтоi
й кусок спискаl
с Lenn
являетсяВ качестве последнего шага создайте список из всех кусков, используя понимание списка:
Пример:
n=11, k=3, l=range(n)
результаты в[range(0, 4), range(4, 8), range(8, 11)]
источник
Это сделает разделение одним выражением:
Список в этом примере имеет размер 18 и разделен на 5 частей. Размер деталей отличается не более чем одним элементом.
источник
Смотрите
more_itertools.divide
:Установить через
> pip install more_itertools
.источник
Вот тот, который добавляет,
None
чтобы сделать списки равной длиныисточник
Вот мое решение:
Производит
источник
Вот генератор, который может обрабатывать любое положительное (целое) количество кусков. Если количество чанков превышает длину входного списка, некоторые чанки будут пустыми. Этот алгоритм чередует короткие и длинные фрагменты, а не разделяет их.
Я также включил некоторый код для тестирования
ragged_chunks
функции.Мы можем сделать это немного более эффективным, экспортируя умножение в
range
вызов, но я думаю, что предыдущая версия более читабельна (и DRYer).источник
Посмотрите на numpy.split :
источник
Реализация с использованием метода numpy.linspace.
Просто укажите количество частей, на которые вы хотите разделить массив. Размеры будут примерно одинаковыми.
Пример :
Дает:
источник
Мое решение, простое для понимания
И самый короткий однострочник на этой странице (написано моей девушкой)
источник
Используя понимание списка:
источник
Другим способом было бы что-то вроде этого, идея здесь в том, чтобы использовать групер, но избавиться от него
None
. В этом случае у нас будут все 'small_parts', сформированные из элементов в первой части списка, и 'large_parts' из более поздней части списка. Длина «больших частей» равна len (small_parts) + 1. Нам нужно рассмотреть x как две разные части.То, как я его настроил, возвращает список кортежей:
источник
Вот еще один вариант, который равномерно распределяет «оставшиеся» элементы по всем кускам, по одному, пока не останется ни одного. В этой реализации более крупные куски возникают в начале процесса.
Например, сгенерируйте 4 фрагмента из списка из 14 элементов:
источник
То же, что и ответ задания , но учитывает списки, размер которых меньше количества чанков.
если n (количество чанков) равно 7, а lst (список для разделения) равен [1, 2, 3], чанки будут [[0], [1], [2]] вместо [[0], [1 ], [2], [], [], [], []]
источник
Вы также можете использовать:
источник
Пример:
l = [a for a in range(97)]
должен состоять из 10 частей, каждая из которых имеет 9 элементов, кроме последней.Вывод:
источник
Допустим, вы хотите разделить список [1, 2, 3, 4, 5, 6, 7, 8] на 3 списка элементов
как [[1,2,3], [4, 5, 6], [7, 8]] , где, если последние оставшиеся элементы меньше 3, они группируются вместе.
Выход: [[1,2,3], [4, 5, 6], [7, 8]]
Там, где длина одной части равна 3. Замените 3 собственным размером куска.
источник
1>
2>
источник
вот моя версия (по мотивам Макса)
источник
Округление linspace и использование его в качестве индекса - более простое решение, чем то, что предлагает amit12690.
источник
Выбрал по этой ссылке , и это то, что мне помогло. У меня был заранее определенный список.
источник
скажем, вы хотите разделить на 5 частей:
источник
Я написал код в этом случае сам:
div_ports (1, 10, 9) вернется
источник
этот код работает для меня (Python3-совместимый):
пример (для типа bytearray , но он работает и для списка s):
источник
Этот предоставляет куски длины <= n,> = 0
Защита
например
источник
Я перепробовал большую часть решений, но они не работали для моего случая, поэтому я создаю новую функцию, которая работает для большинства случаев и для любого типа массива:
источник