Python中如何拆包指定数量的元素?

5
有没有办法使用“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

解决这个问题的正常/规范/Pythonic方式是什么?


你使用的是哪个版本的Python? - thefourtheye
5
你能不能简单地切片你的参数,如 first_arrangement = args[1:5] ...? - Julien Spronck
对于第一个问题的回答是,无法使用*来完成这个操作。 - MJeffryes
Python 3 - 是的,我只是想知道是否有类似于splat操作符的更简洁的东西。 - Anonymous
好的,谢谢@MJeffryes,我会继续关注看看人们为这个用例提出什么解决方案。 - Anonymous
2个回答

2

我认为在Python中,这样做的规范和惯用方式是将责任放在您正在迭代的生成器上。我会定义一个生成器函数如下:

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)

很好的答案... 我会补充 for num,arr in generate_arangements(data) - Joran Beasley
@JoranBeasley 谢谢!好建议,我已经将它添加到我的答案末尾。 - jme

1

不清楚您接收数据的格式。这些是字符串、文件中的数据等等。假设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]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接