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

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

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

Введение

Разбиение строк и списков — это типичная задача программиста. Иногда нам приходится разбивать наши данные особым образом, но чаще — на равные части.

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

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

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

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

На равные части из n элементов

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

Давайте создадим новый файл и начнем программирование:

def func_chunk(lst, n):
    for x in range(0, len(lst), n):
        e_c = lst[x : n + x]

        if len(e_c) < n:
            e_c = e_c + [None for y in range(n - len(e_c))]
        yield e_c


print(list(func_chunk([9, 8, 7, 6, 5, 4, 3, 2, 1], 3)))

Приведенная выше функция func_chunk принимает аргументы: lst для списка и chunk_size для числа, на которое его нужно разделить. Функция выполняет итерацию по списку с приращением размера фрагмента n.

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

Вывод программы:

[[9, 8, 7], [6, 5, 4], [3, 2, 1]]

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

Python имеет утилиты для упрощения этого процесса. Мы можем использовать функцию zip_longest из itertools для упрощения предыдущей функции.

Давайте создадим новый файл и напишем следующий код:

from itertools import zip_longest


def func_chunk_itertools(lst):
    i_ = iter(lst)
    return list(zip_longest(i_, i_, i_, i_))


print(func_chunk_itertools([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]))

Этот код повторяет элементы и возвращает фрагмент желаемой длины на основе предоставленных вами аргументов.

Мы поместили в коде 4 аргументf i_. Функция zip_longest агрегирует и возвращает элементы из каждой итерации. В этом случае она будет агрегировать элементы из списка, который повторяется 4. Затем создается множество итераторов, содержащих 4 последовательных элементов, которые после преобразуются в список и возвращаются.

Вывод программы будет таков:

[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, None)]

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

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

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


print(
    list(
        func_chunks_generators(
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 54, 3, 2, 2, 1], 4
        )
    )
)

Этот генератор дает подсписок, содержащий n элементов. В конце концов, это дало бы подсписок для каждой части.

Вывод программы:

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 8, 7], [6, 54, 3, 2], [2, 1]]

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

На n равных частей

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

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

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

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

import math


def func_chunks_num(lst, c_num):
    n = math.ceil(len(lst) / c_num)

    for x in range(0, len(lst), n):
        e_c = lst[x : n + x]

        if len(e_c) < n:
            e_c = e_c + [None for y in range(n - len(e_c))]
        yield e_c


print(list(func_chunks_num([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], c_num=3)))

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

Вывод программы:

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, None]]

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

Заключение

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

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

Егор Егоров

Программирую на Python с 2017 года. Люблю создавать контент, который помогает людям понять сложные вещи. Не представляю жизнь без непрерывного цикла обучения, спорта и чувства юмора.

Ссылка на мой github есть в шапке. Залетай.

Оцените автора
Егоров Егор
Добавить комментарий

  1. Сергей

    Помогите во такую решить: есть словарь :
    dic = {
    ‘a’: [‘123’, ‘234’, ‘345’, ]
    }
    как вывести такое?:
    123
    234
    345

    Ответить
    1. Сергей

      Нет… сори… туплю уже ночью…
      вот такой словарь
      dic = {
      ‘a’: [‘123456’, ‘234567’, ‘132456’, ‘345678’, ‘123456’, ‘765432’]
      }
      надо вывести:
      123456 234567
      123456 345678
      123456 765432

      Ответить