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

moo*_*eep 45 python iterable-unpacking

在Python 3中,我可以执行以下操作(另请参阅PEP3132 on Extended Iterable Unpacking):

a, *b = (1, 2, 3)
# a = 1; b = (2, 3)
Run Code Online (Sandbox Code Playgroud)

我能做些什么才能在Python 2.x中实现同样优雅?


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

a, b = (1, 2, 3)[0], (1, 2, 3)[1:]
# a = 1; b = (2, 3)
Run Code Online (Sandbox Code Playgroud)

moo*_*eep 30

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

许多算法需要在"first,rest"对中拆分序列:

first, rest = seq[0], seq[1:]
Run Code Online (Sandbox Code Playgroud)

[...]

此外,如果右侧值不是列表,而是可迭代的,则必须先将其转换为列表才能进行切片; 为了避免创建这个临时列表,人们不得不诉诸

it = iter(seq)
first = it.next()
rest = list(it)
Run Code Online (Sandbox Code Playgroud)

在这个问题的答案中给出的其他方法:

函数参数列表解包方法

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

def unpack(first, *rest): 
  return first, rest
first, rest = unpack( *seq )
Run Code Online (Sandbox Code Playgroud)

我想知道为什么它在解包函数参数列表中实现,但不适用于正常的元组解包.

发电机方法

积分.还需要自定义函数实现.关于第一个变量的数量有点灵活.

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)
Run Code Online (Sandbox Code Playgroud)

我猜,最可能是PEP中提到的pythonic?

  • 截至今天,PEP 3132似乎只适用于Python 3.x. 我可以确认'first,*rest = seq'语法在Python 2.7.5中不起作用(你在上面提到2.x). (3认同)

Fél*_*net 8

我可能是错的,但据我所知

a, *b = (1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

只是用于对元组进行切片和索引的语法糖。我发现它很有用,但不是很明确。


geo*_*org 8

我有这个方便的小功能:

def just(n, seq):
    it = iter(seq)
    for _ in range(n - 1):
        yield next(it, None)
    yield tuple(it)
Run Code Online (Sandbox Code Playgroud)

例如:

a, b, c = just(3, range(5))
print a, b, c
## 0 1 (2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

也适用于较少的参数:

a, b, c = just(3, ['X', 'Y'])
print a, b, c
## X Y ()
Run Code Online (Sandbox Code Playgroud)

在回复评论时,您还可以定义:

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
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

p = (1,2,3)
a, b = take2(*p)
print a, b
## 1 (2, 3)
Run Code Online (Sandbox Code Playgroud)