Effective Python 第13条:使用带星号的unpacking来接受不定变量

假如有一个存储数字的列表,我们要把列表分成3部分:最大值、倒数第二大的值和其他值。使用切片如下:

_list = [5, 9, 10, 1, 6, 20, 12, 8]
# 先排序
sorted_list = sorted(a_list, reverse=True)
max_value, second_value, others = sorted_list[0], sorted_list[1], sorted_list[2:]
print(max_value, second_value, others)
# 20 12 [10, 9, 8, 6, 5, 1]

这样写比较乱,且容易出错。
推荐使用带星号的表达式来解决。也属于unpacking操作,如下:

a_list = [5, 9, 10, 1, 6, 20, 12, 8]
# 先排序
sorted_list = sorted(a_list, reverse=True)
max_value, second_value, *others = sorted_list
print(max_value, second_value, others)
# 20 12 [10, 9, 8, 6, 5, 1]

*others把前面列表除前两个元素全部接受了,这样写更加简洁。

带星号的表达式可以出现在任意位置,所以可以捕获序列中的任意一段元素。如下:

a_list = [5, 9, 10, 1, 6, 20, 12, 8]
# 先排序
sorted_list = sorted(a_list, reverse=True)
max_value, *others, min_value = sorted_list
print(min_value, max_value, others)  # 1 20 [12, 10, 9, 8, 6, 5]
*others, second_smallest, smallest = sorted_list
print(smallest, second_smallest, others)  # 1 5 [20, 12, 10, 9, 8, 6]

注意:
1.至少要有一个普通变量和带星号的表达式搭配,否则出现SyntaxError
2.对于单层结构,同一级里面最多出现一个带星号的unpacking,否则也会出现SyntaxError

对于多层结构,每一层都可以出现各自带星号的unpacking,但是不推荐这样做。下面举一个例子:

car_inventory = {
    'Downtown': ('Silver Shadow', 'Pinto', 'DMC'),
    'Airport': ('Skyline', 'Viper', 'Gremlin', 'Nova')
}
(
    (loc1, (best1, *rest1)),
    (loc2, (best2, *rest2))
) = car_inventory.items()  # .items用来遍历字典的键和值
print(f'Best at {loc1} is {best1}, {len(rest1)} others')
print(f'Best at {loc2} is {best2}, {len(rest2)} others')
# Best at Downtown is Silver Shadow, 2 others
# Best at Airport is Skyline, 3 others

注意星号表达式了会形成一个列表,如果要拆分的序列里没有元素留给星号表达式了,则列表就为空。

带星号的表达式unpacking也可以用在迭代器上或函数的返回值上。如下:

def get_something():
    return 1, 2, 3, 4
a, *others = get_something()
print(a, others)  # 1 [2, 3, 4]

注意:带星号的这一部分总会形成一份列表,所以列表很大时可能耗尽计算机内存导致程序崩溃。使用前最好可以确认不会导致这种情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值