需要从某个可迭代对象中分解出 N 个元素,Python 的 “*表达式” 可以用来解决这个问题,有以下经典例子:

1
2
3
4
5
6
7
*trailing, current = [10, 8, 7, 1, 9, 5, 10, 3]
print(trailing)
print(current)

# 结果为:
# [10, 8, 7, 1, 9, 5, 10]
# 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
records = [
('foo', 1, 2),
('bar', 'hello'),
('foo', 3, 4),
]


def do_foo(x, y):
print('foo', x, y)


def do_bar(s):
print('bar', s)


for tag, *args in records:
if tag == 'foo':
do_foo(*args)
elif tag == 'bar':
do_bar(*args)

# 结果为:
# foo 1 2
# bar hello
# foo 3 4

当和某些特殊的字符串处理操作相结合,比如做拆分(splitting)操作时,这种*式的语法所支持的分解操作也非常有用:

1
2
3
4
5
6
7
8
9
10
line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'
uname, *fields, homedir, sh = line.split(':')
print(uname)
print(homedir)
print(sh)

# 结果为:
# nobody
# /var/empty
# /usr/bin/false

有时候可能想分解出某些值然后丢弃它们,可以使用诸如 _ 或者 ign(ignored)等常用来表示待丢弃值的变量名:

1
2
3
4
5
6
7
8
record = ('ACME', 50, 123.45, (12, 18, 2012))
name, *_, (*_, year) = record
print(name)
print(year)

# 结果为:
# ACME
# 2012

*表达式 在递归中的应用:

1
2
3
4
5
6
7
8
9
10
11
def sum(items):
head, *tail = items
return head + sum(tail) if tail else head


items = [1, 10, 7, 4, 5, 9]
print(sum(items))


# 结果为:
# 36

其中 return head + sum(tail) if tail else head 的意思是:

1
2
3
4
if tail:
return head + sum(tail)
else:
return head

但是注意,递归不是 Python 的强项,这是因为其内在的递归限制所致,因此最后一个例子在实践中没有太大意义。


参考:《Python Cookbook》http://stackoverflow.com/questions/26085990/i-dont-understand-this-python-sentence-if-tail-else-head