Подтвердить что ты не робот

Нарезка списка в список подписок

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

Например, если наш исходный список:

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

И наша длина суб-списка равна 3, тогда мы ищем:

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

Аналогично, если длина нашего списка составляет 4, то мы ищем:

output = [ [1, 2, 3, 4], [5, 6, 7, 8], ... ]
4b9b3361

Ответ 1

[input[i:i+n] for i in range(0, len(input), n)]        # use xrange in py2k

где n - длина фрагмента.

Поскольку вы не определяете, что может произойти с конечным элементом нового списка, когда количество элементов в input не делится на n, я предположил, что это не имеет значения: с этим вы будете получить последний элемент равным 2, если n равно 7, например.

Ответ 2

Документация модуля itertools содержит следующие recipe:

import itertools

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.izip_longest(fillvalue=fillvalue, *args)

Эта функция возвращает итератор кортежей требуемой длины:

>>> list(grouper(2, [1,2,3,4,5,6,7]))
[(1, 2), (3, 4), (5, 6), (7, None)]

Ответ 3

Действительно pythonic вариант (python 3):

list(zip(*(iter([1,2,3,4,5,6,7,8,9]),)*3))

Итератор списка создается и превращается в кортеж с 3x тем же самым итератором, а затем распаковывается на zip и заносится в список снова. Одно значение извлекается из каждого итератора по zip, но поскольку существует только один объект итератора, внутренний счетчик увеличивается глобально для всех трех.

Ответ 4

Мне нравится решение SilentGhost.

Мое решение использует функциональное программирование в python:

group = lambda t, n: zip(*[t[i::n] for i in range(n)])
group([1, 2, 3, 4], 2)

дает:

[(1, 2), (3, 4)]

Это предполагает, что размер списка входных данных делится на размер группы. Если нет, непарные элементы не будут включены.