您的位置:首页 > 编程语言 > Python开发

python CookBook 3 1.2 拆解任意长度的可迭代对象

2014-05-07 11:30 429 查看
问题:

你需要从一个可迭代对象中拆解出N个元素,但是它可能多于N个元素并导致抛出“too many values to unpack”的异常

解决:
python的“带星参数”可以搞定这个问题。比如说,你开了一门课并且决定在期末的时候,你将去掉第一次和最后一次的家庭作业的成绩再计算出剩余的平均成绩。如果只有四次作业,那就是小意思妥妥的无压力秒杀。可如果是有24次作业呢? 带星参数将能很好地解决这个问题:

def drop_first_last(grades):
first, *middle, last = grades

return avg(middle)

另一个栗子,假设你有包含了用户名,邮箱及一坨长度任意的电话号码。你可以这么处理:
P.S python2.7.6会报错

书上的例子有一处打印错
>>> name, email, *phone_numbers = record
>>> record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
>>> name, email, *phone_numbers = record #书上此处为 user_record
>>> name
'Dave'
>>> email
'dave@example.com'
>>> phone_numbers
['773-555-1212', '847-555-1212']
>>>


无论有多少个要拆解或为None phones_number变量总会是一个列表,因此在对phones_number变量做处理时,无须做是否为列表的类型检查。(撒花!!)
带星参数 也可用于列表开头。比如说,你有一个关于你公司过去8个季度的销售数据序列。如果你想知道最后一个季度与前七个季度的平均值相比哪个更好。你可以这么处理:
*trailing_qtrs, current_qtr = sales_record
trailing_avg = sum(trailing_qtrs) / len(trailing_qtrs)
return avg_comparison(trailing_avg, current_qtr)

栗子!栗子:

>>> *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3]
>>> trailing
[10, 8, 7, 1, 9, 5, 10]
>>> current
3
>>>


讨论:
可扩展的迭代对象的拆解适用于拆解长度未知或任意的可迭代对象。经常的情况是这类可迭代对象的一些结构是已知的。带星参数可以方便让你访问到相关的元素。

>>> 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
>>>
带星的拆解 在诸如抄截字符串时也很有用。

>>> line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'
>>> uname, *fields, homedir, sh = line.split(':')
>>> uname
'nobody'
>>> homedir
'/var/empty'
>>> sh
'/usr/bin/false'
>>>


有时,我会想干掉分离出来的元素。你不能就单单使用带星参数了,你可以使用一个常见的表示可抛弃的变量名 像是 ‘_’或者 ign(ignored)
>>> record = ('ACME', 50, 123.45, (12, 18, 2012))
>>> name, *_, (*_, year) = record
>>> name
'ACME'
>>> year
2012
>>>


列表:
>>> items = [1, 10, 7, 4, 5, 9]
>>> head, *tail = items
>>> head
1
>>> tail
[10, 7, 4, 5, 9]
>>>


有人会想到写个方法以便执行一些递归算法

>>> def sum(items):
head, *tail = items
return head + sum(tail) if tail else head
>>> sum(items)
36
>>>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python cookbook 3
相关文章推荐