7:Python推导式与序列解包

一丶推导式(comprehensions)

又称解析式

  • 利用列表推导式、字典推导式、集合推导式可以从一个数据对象构建另一个新的数据对象
  • 利用生成器推导式可以构建生成器对象

1. 列表推导式(list comprehension)

是Python开发时用得最多的技术之一,表示对可迭代(Iterable)对象的元素进行遍历、过滤或再次计算,生成满足条件的新列表。利用列表推导式更加简洁。由于Python内部对列表推导式做了大量优化,还能保证较快的运行速度。

普通for循环
>>> n=[10,-33,21,5,-7,-9,3,28,-16,37]
>>> number=[]
>>> for i in n:
	        number.append(i*2)
>>> number
[20, -66, 42, 10, -14, -18, 6, 56, -32, 74]
列表推导式
>>> n=[10,-33,21,5,-7,-9,3,28,-16,37]
>>> number=[i*2 for i in n]
>>> number
[20, -66, 42, 10, -14, -18, 6, 56, -32, 74]

>>> n=[[10,-33,21],[5,-7,-9,3,28,-16,37]]
>>> number=[j*2 for i in n for j in i]
>>> number
[20, -66, 42, 10, -14, -18, 6, 56, -32, 74]

>>> n=[10,-33,21,5,-7,-9,3,28,-16,37]
>>> number=[i*2 if i%2==0 else i*3 for i in n if i>0]
>>> number
[20, 63, 15, 9, 56, 111]
列表推导式与函数
>>> import random
>>> rlist=[random.randint(30,80) for i in range(15)] #使用randint()函数
>>> rlist
[30, 45, 68, 60, 73, 49, 66, 72, 66, 33, 52, 52, 61, 42, 51]


>>> def ff(x):
	        if x%3==0:
		        x/=3
	        elif x%7==0:
		        x*=2
	        else:
		        x*=5
	        return x
 
>>> number=[ff(i) for i in rlist] #使用自定义的ff()函数
>>> number
[10.0, 15.0, 340, 20.0, 365, 98, 22.0, 24.0, 22.0, 11.0, 260, 260, 305, 14.0, 17.0]

2. 字典推导式

字典推导式和列表推导式的使用方法类似,只不过将方括号变成花括号,并且需要两个表达式,一个生成键,一个生成值,两个表达式之间使用冒号分隔,最后生成的是字典。

>>> name= ['Bob','Tom','Alice','Jerry','Wendy','Smith']
>>> score=[86,78,98,90,47,80]
>>> dd={i:j for i,j in zip(name,score)}
>>> dd
{'Bob': 86, 'Tom': 78, 'Alice': 98, 'Jerry': 90, 'Wendy': 47, 'Smith': 80}

以名字为键、成绩为值组成新字典exdd,新字典中的键值对只包含成绩80及以上的。
>>> exdd={i:j for i,j in zip(name,score) if j>=80}
>>> exdd
{'Bob': 86, 'Alice': 98, 'Jerry': 90, 'Smith': 80}

3. 生成器推导式

  • 生成器推导式用法与列表推导式类似,把列表推导式的方括号改成圆括号。它与列表推导式最大的区别是:生成器推导式的结果是一个生成器对象,是一种迭代器(Iterator);而列表推导式的结果是一个列表。
  • 生成器对象可以通过for循环或者__next__()方法、next()函数进行遍历,也可以转换为列表或元组,但是不支持使用下标访问元素,已经访问过的元素也不支持再次访问。当所有元素访问结束之后,如果想再次访问就必须重新创建该生成器对象。
>>> gen=(int(i/3) for i in range(1,10) if i%3==0)
>>> gen
<generator object <genexpr> at 0x0000000002F0BB88>
>>> list(gen) #生成器对象转换为列表
[1, 2, 3]
>>> gen.__next__() #不能再次访问
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    gen.__next__()
StopIteration
>>> gen=(int(i/3) for i in range(1,10) if i%3==0) #重新生成生成器对象
>>> gen.__next__()  #访问下一个元素
1
>>> next(gen)       #访问下一个元素
2
>>> gen.__next__()
3
>>> next(gen)        #访问完毕,不能再次访问
Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    next(gen)
StopIteration
>>> gen=(int(i/3) for i in range(1,10) if i%3==0)
>>> for i in gen:       #for循环遍历
	        print(i,end=' ')
 
1 2 3


二丶 序列解包

序列解包(Sequence Unpacking)是Python语言赋值语句的一种技巧和方法,在Python中经常用到。

1. 多变量同时赋值

>>> x,y,z='a','b','c'
>>> x
'a'
>>> y
'b'
>>> z
'c'


2. 一个对象值赋给多个变量

>>> x,y,z=['a','b','c'] 
>>> print(x,y,z)
a b c
>>> x,y,z=sorted([22,33,11])   #sorted([22,33,11])的结果是排好序的列表
>>> print(x,y,z)
11 22 33
>>> x='a','b','c'
>>> x
('a', 'b', 'c')
>>> i,j,k=x            #x是一个元组,这个元组可以进一步赋值到多个变量上
>>> print(i,j,k)
a b c

3. 交换两个变量的值

>>> x,y=44,55
>>> y,x=x,y       
>>> print(x,y)
55 44


4. 切片支持序列解包

>>> a=list(range(5))
>>> a
[0, 1, 2, 3, 4]
>>> a[1:4]=map(str,[11,22,33])
>>> a
[0, '11', '22', '33', 4]

5. 使用序列解包同时遍历多个序列

>>> names=['Lily','Tom','Mary']
>>> height=[165,177,168]
>>> for i,j in zip(names,height):
	        print(i,j,end=' ')
 
	
Lily 165 Tom 177 Mary 168

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章