关于python:如何将长度为n的元组解包为m<n个变量

How to unpack tuple of length n to m<n variables

本问题已经有最佳答案,请猛点这里访问。

在 Python 3 中,我可以执行以下操作(另请参阅有关扩展可迭代解包的 PEP3132):

1
2
a, *b = (1, 2, 3)
# a = 1; b = (2, 3)

我该怎么做才能在 Python 2.x 中实现同样的优雅?

我知道我可以使用单元素访问和切片操作,但我想知道是否有更 Pythonic 的方式。到目前为止我的代码:

1
2
a, b = (1, 2, 3)[0], (1, 2, 3)[1:]
# a = 1; b = (2, 3)


我发现相关的 PEP3132 也为 Python 2.x 提供了一些示例:

Many algorithms require splitting a sequence in a"first, rest" pair:

1
first, rest = seq[0], seq[1:]

[...]

Also, if the right-hand value is not a list, but an iterable, it has to be converted to a list before being able to do slicing; to avoid creating this temporary list, one has to resort to

1
2
3
it = iter(seq)
first = it.next()
rest = list(it)

此问题的答案中给出的其他方法:

函数参数列表解包方法

需要额外的函数定义/调用:

1
2
3
def unpack(first, *rest):
  return first, rest
first, rest = unpack( *seq )

我想知道为什么它在解包函数参数列表中实现,而不是在普通元组解包中实现。

生成器方法

学分。还需要自定义函数实现。关于第一个变量的数量更灵活一些。

1
2
3
4
5
6
def unpack_nfirst(seq, nfirst):
  it = iter(seq)
  for x in xrange(nfirst):
    yield next(it, None)
  yield tuple(it)
first, rest = unpack_nfirst(seq, 1)

我猜最pythonic的可能是上面PEP中提到的那些?


我可能错了,但据我所知

1
a, *b = (1, 2, 3)

只是用于切片和索引元组的语法糖。我觉得它很有用,但不是很明确。


我有这个方便的小功能:

1
2
3
4
5
def just(n, seq):
    it = iter(seq)
    for _ in range(n - 1):
        yield next(it, None)
    yield tuple(it)

例如:

1
2
3
a, b, c = just(3, range(5))
print a, b, c
## 0 1 (2, 3, 4)

也适用于较少的参数:

1
2
3
a, b, c = just(3, ['X', 'Y'])
print a, b, c
## X Y ()

响应评论,你也可以定义:

1
2
3
4
def take2(a, *rest): return a, rest
def take3(a, b, *rest): return a, b, rest
def take4(a, b, c, *rest): return a, b, rest
... etc

并像这样使用它:

1
2
3
4
p = (1,2,3)
a, b = take2(*p)
print a, b
## 1 (2, 3)


我认为没有比你发布的更好的方法了,但这里有一个使用 iter

的替代方法

1
2
3
4
5
6
7
>>> x = (1,2,3)
>>> i = iter(x)
>>> a,b = next(i), tuple(i)
>>> a
1
>>> b
(2, 3)

不确定上下文,但是 .pop(0) 呢?

我看到您的示例中有元组,但是如果您想做那种事情,我认为列表会更合适? (除非问题中没有给出它们不可变的充分理由。)

1
2
b = [1,2,3]
a = b.pop(0)