使用Python的itertools的二维表索引生成器

时间:2019-04-22 08:41:32

标签: python iterator generator sequence itertools

我想将列表中的项放在表的顺序索引上,列数由输入控制。我知道如何通过在每列的末尾增加或重置整数来“无聊”地执行此操作,但是我认为使用Python的itertools库可能有一种更优雅的方法。

考虑此列表:

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 个答案:

答案 0 :(得分:1)

您似乎可以使用repeat

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为我们提供了行号。