数据结构和算法
一、将序列分解为单独的变量
1.1 问题
我们有一个包含N个元素的元祖或列表,现在想将它分解为N个单独的变量。
1.2 解决方案
任何序列(或可迭代的对象)都可以通过一个简单的赋值操作来分解为单独的变量。唯一的要求是变量的总数和结构要与序列相吻合。例如:
>>> p = (4,5) >>> x,y = p >>> x 4 >>> y 5 >>> data = ['flash',50,91.1,(2016,5,6)] >>> name,shares,price,date = data >>> name 'flash' >>> date (2016, 5,6) >>> name,shares,price,(year,mon,day) = data >>> name 'flash' >>> year 2016 >>> day 6 #如果元素的数量不匹配,就会报错 >>> p = (4,5) >>> x,y,z = p Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: not enough values to unpack (expected 3, got 2)
1.3 扩展
实际上不仅仅只是元祖或列表,只要对象恰好是可迭代,那么就可以执行分解操作。这包括字符串、文件、迭代器以及生成器。例如:
#字符串分解 >>> s = 'Hello' >>> a,b,c,d,e = s >>> a 'H' >>> c 'l' >>> e 'o' #还可以以一个用不到的变量名来作为丢弃的值的名称 >>> data = ['flash',50,91.1,(2012,12,21)] >>> _,shares,price,_ = data >>> shares 50 >>> price 91.1
二、从任意长度的可迭代对象中分解元素
2.1 问题
需要从某个可迭代对象中分解出N个元素,但是这个可迭代对象的长度可能超过N,这会导致出现"分解的值过多(too many values to unpack)"的异常。
2.2 解决方案
Python的"*表达式"可以用来解决这个问题。
1 #掐头去尾求平均值 2 def drop_first_last(grades=[12,34,56,78,90,100]): 3 first,*middle,last = grades 4 print(sum(middle)/len(middle)) 5 drop_first_last() 6 7 #结果是34、56、78、90这四个数字的平均值 64.5
>>> user = 'mail:x:8:8:mail:/var/mail:/usr/sbin/nologin' >>> name,*fields,homedir,sh = user.split(':') >>> name 'mail' >>> homedir '/var/mail' >>> sh '/usr/sbin/nologin'
运维因自动化而有趣!