Генератор индекса двумерной таблицы с использованием Python itertools - PullRequest
1 голос
/ 22 апреля 2019

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

Рассмотрим этот список:

items = ["Apple", "Orange", "Pear", "Strawberry", "Banana"]

Вот скучный путь:

def table_indexes(items, ncol):
    col = 0
    row = 0

    for item in items:
        yield (col, row)
        col += 1
        if col >= ncol:
            # end of row
            col = 0
            row += 1

Это приведет к индексам, которые помещают элементы в следующие индексы таблицы:

| Apple  | Orange     |
| Pear   | Strawberry |
| Banana |            |

Я хотел бы найти функцию в itertools или в другом месте, которая может дать последовательность пар индексов, где один индекс в каждой паре циклически повторяет последовательность чисел (номера столбцов), а другой индекс увеличивается на 1 каждый раз повторяется первый цикл? Вот так:

def table_indexes(items, ncol):
    cols = ... # e.g. itertools.cycle(range(ncol))
    rows = ... # needs to be an iterator yielding sequences of [i]*ncol where i is the current row index
    yield zip(cols, rows):

Можно ли расширить решение до N измерений?

1 Ответ

1 голос
/ 22 апреля 2019

похоже, что вы можете использовать повтор .

from itertools import chain, repeat

def table_indexes(items, ncol):
    cols = chain.from_iterable(repeat(range(ncol), len(items)//ncol + 1))
    for x, (col, item) in enumerate(zip(cols, items)):
    yield x//ncol, col, item

items = ["Apple", "Orange", "Pear", "Strawberry", "Banana"]
list(table_indexes(items, 3))

выход:

[(0, 0, 'Apple'),
 (0, 1, 'Orange'),
 (0, 2, 'Pear'),
 (1, 0, 'Strawberry'),
 (1, 1, 'Banana')]

более подробно, повтор дает нам список столбцов

repeat(range(ncol), len(items)//ncol + 1) -> [[0, 1, 2], [0, 1, 2]]

и пока мы перебираем перечисление элементов, конструкция x // ncol дает нам номер строки.

...