Как разбить список на четные части в Python

Введение Разделение строк и списков - распространенные действия при программировании на Python и других языках. Иногда нам приходится разбивать наши данные особым образом, но чаще - на равные части. В языке нет встроенной функции для этого, и в этом руководстве мы рассмотрим, как разбить список на четные части в Python. В большинстве случаев вы можете использовать генераторы: def chunk_using_generators (lst, n): for i in range (0, len (lst), n): yield lst [i: i + n]

Вступление

Разделение строк и списков - обычные действия при программировании на Python и других языках. Иногда нам приходится разбивать наши данные особым образом, но чаще - на равные части.

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

В большинстве случаев вы можете получить с помощью генераторов:

 def chunk_using_generators(lst, n): 
 for i in range(0, len(lst), n): 
 yield lst[i:i + n] 

Хотя есть и другие интересные способы сделать это, каждый со своими плюсами и минусами!

Разбить список на четные блоки по N элементов

Список можно разделить в зависимости от размера определенного фрагмента. Это означает, что мы можем определить размер чанка. Если подмножество списка не умещается в размере определенного фрагмента, необходимо вставить заполнители вместо пустых держателей элементов. В этих случаях мы будем использовать None

Давайте создадим новый файл с именем chunk_based_on_size.py и добавим следующее содержимое:

 def chunk_based_on_size(lst, n): 
 for x in range(0, len(lst), n): 
 each_chunk = lst[x: n+x] 
 
 if len(each_chunk) < n: 
 each_chunk = each_chunk + [None for y in range(n-len(each_chunk))] 
 yield each_chunk 
 
 print(list(chunk_based_on_size([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 7))) 

Вышеупомянутая chunk_based_on_size() принимает аргументы: lst для списка и chunk_size для числа, по которому его нужно разделить. Функция выполняет итерацию по списку, увеличивая размер блока n . Ожидается, что размер каждого фрагмента будет указан в качестве аргумента. Если элементов недостаточно для разделения одинакового размера, оставшиеся неиспользуемые элементы заполняются None .

Запуск этого сценария возвращает следующий список списков:

 $ python3 chunk_based_on_size.py 
 [[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, None]] 

Список разбит на равные части по 7 элементов в каждой.

В Python есть утилиты, упрощающие этот процесс. Мы можем использовать функцию zip_longest itertools чтобы упростить предыдущую функцию. Создадим новый файл chunk_using_itertools.py и добавим следующий код:

 from itertools import zip_longest 
 
 def chunk_using_itertools(lst): 
 iter_ = iter(lst) 
 return list(zip_longest(iter_, iter_, iter_, iter_, iter_, iter_, iter_)) 
 
 print(chunk_using_itertools([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])) 

Этот код выполняет итерацию элементов и возвращает фрагмент желаемой длины в зависимости от предоставленных вами аргументов. Мы поместили здесь 7 iter_ аргументов. Функция zip_longest() агрегирует и возвращает элементы из каждой итерации. В этом случае он будет объединять элементы из списка, который повторяется 7 раз за один раз. Затем создаются многочисленные итераторы, содержащие 7 последовательных элементов, которые затем преобразуются в список и возвращаются.

Когда вы выполните этот фрагмент, это приведет к:

 $ python3 chunk_using_itertools.py 
 [[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, None]] 

Эта более короткая функция производит тот же ввод. Однако он гораздо более ограничен, поскольку нам приходится вручную писать, сколько элементов мы хотим в коде, и немного неудобно просто поместить кучу iter_ в zip_longest() .

Лучшим решением будет использование генераторов. Создадим новый файл chunk_using_generators.py :

 def chunk_using_generators(lst, n): 
 for i in range(0, len(lst), n): 
 yield lst[i:i + n] 
 
 print(list(chunk_using_generators([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 7))) 

Этот генератор формирует подсписок, содержащий n элементов. В конце концов, это дало бы подсписок для каждого фрагмента. Запуск этого кода дает следующий результат:

 $ python3 chunk_using_generators.py 
 [[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13]] 

Это решение работает лучше всего, если вам не нужно заполнение с помощью None или иначе.

Разбить список на N четных фрагментов

В предыдущем разделе мы разделили список в зависимости от размера отдельных фрагментов, чтобы в каждом фрагменте было одинаковое количество элементов. Есть другой способ интерпретировать эту проблему. Что мы делаем, когда хотим разбить список не на основе количества элементов в каждом фрагменте, а на основе количества фрагментов, которые мы хотим создать?

Например, вместо того, чтобы разбивать список на части, каждый из которых состоит из 7 элементов, мы хотим разбить список на 7 четных частей. В этом случае мы можем не знать размер каждого фрагмента.

Логика аналогична предыдущим решениям, однако размер блока - это максимальное значение длины списка, деленное на количество требуемых блоков. Как и в предыдущих примерах кода, если в блоке есть свободные места, они будут заполнены значением заполнителя None :

 import math 
 
 def chunk_based_on_number(lst, chunk_numbers): 
 n = math.ceil(len(lst)/chunk_numbers) 
 
 for x in range(0, len(lst), n): 
 each_chunk = lst[x: n+x] 
 
 if len(each_chunk) < n: 
 each_chunk = each_chunk + [None for y in range(n-len(each_chunk))] 
 yield each_chunk 
 
 print(list(chunk_based_on_number([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], chunk_numbers=7))) 

Мы определяем, сколько списков нам нужно создать, и сохраняем это значение в n . Затем мы создаем подсписок для двух элементов одновременно, дополняя вывод в случае, если размер нашего блока меньше желаемой длины.

Когда мы запустим этот файл, мы увидим:

 $ python3 chunk_based_on_number.py 
 [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, None]] 

Как видно из выходных данных выше, список был разделен на 7 отдельных списков равного размера на основе предоставленного аргумента chunk_numbers .

Заключение

В этой статье мы рассмотрели некоторые способы, которыми список может быть разделен на части и списки одинакового размера на основе пользовательских методов и с помощью встроенных модулей.

Решения, упомянутые в этом руководстве, не ограничиваются определенными здесь, но есть несколько других творческих способов, с помощью которых вы также можете разделить свой список на равные части.

comments powered by Disqus