在 Python 中打开给定数量的项目?

Unpack a given number of items in Python?

有没有什么方法可以使用 'splat' 运算符(例如 a, *rest = somelist)来消耗一定数量的项目?

用例:我想将一些输入拆分为一个数字、一个列表列表、另一个数字和另一个列表列表。

我的输入是这样的:

5
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
5
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

我想要 first_numfirst_arrangementsecond_numsecond_arrangement 这样的名称:

first_num == 5
first_arrangement == [[1, 2, 3, 4], [5, 6, 7, 8], ...]

等等。

要做到这一点,能够从我已经产生的可迭代对象中消耗一定数量的项目会很有用。像这样的东西作为中间步骤是理想的: first_num, *[4]first_arrangement, second_num, *[4]second_arrangement = lines

解决此问题的 normal/canonical/Pythonic 方法是什么?

不清楚您接收的数据是什么格式。这些字符串、文件中的数据等。假设 data 是样本输入的 StringIO 对象。 您可以在迭代器上使用 itertools.islice 来提取 n 项,例如:

>>> from itertools import islice
>>> d = iter(data)
>>> first_num = int(next(d))
>>> first_arrangement = [[int(x) for x in l.split()] for l in islice(d, 4)]
>>> print(first_num, first_arrangement)
5  [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

我认为执行此操作的规范的 pythonic 方法是将责任放在您正在迭代的生成器上。我会像这样定义一个生成器函数:

import itertools

def generate_arrangements(iterable, size=4):
    iterator = iter(iterable)
    while True:
        yield next(iterator)
        yield list(list(row) for row in itertools.islice(iterator, size))

假设您的数据在这样的列表中:

data = [
    5,
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16],
    5,
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16]
]

然后写:

first_num, first_arr, second_num, second_arr = generate_arrangements(data)

给你你想要的输出:

>>> first_num
5
>>> first_arr
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

你也可以同时产生数量和排列,让用户做一些额外的解包,这可能是一个更自然的方法:

import itertools

def generate_arrangements(iterable):
    iterator = iter(iterable)
    while True:
        number =  next(iterator)
        arrangement = list(list(row) for row in itertools.islice(iterator, 4))
        yield number, arrangement

(first_num, first_arr), (second_num, second_arr) = generate_arrangements(data)

正如@JoranBeasley 在评论中所写,这种形式使得在 for 循环中使用元组解包变得容易,如下所示:

for num,arr in generate_arrangements(data):
    print(num) 
    print(arr)