- 一、 需求:排除list的第一個(gè)以及最后一個(gè)元素之后曲秉,進(jìn)行平均數(shù)的求解
def avg(agrs):
return sum(agrs)/len(agrs)
def drop_first_last(grades):
first, *middle, last = grades
return avg(middle)
print(drop_first_last((1, 2, 3, 4, 5, 6, 7, 8, 9)))
輸出:5.0
注意middle
變量永遠(yuǎn)都是列表類(lèi)型,不管中間有多少(包括0),所以任何使用到middle
變量的代碼就不需要做多余的類(lèi)型檢查去確認(rèn)它是否是列表類(lèi)型了.
- 二胸嘁、從一個(gè)集合中獲得最大或者最小的N個(gè)元素列表
heaps模塊有兩個(gè)函數(shù):nlargest()
與smallest()
可以解決這個(gè)問(wèn)題
import heapq
nums = [1,8,2,23,7,-4,18,23,42,37,2]
print(heapq.nlargest(3,nums))#獲取最大的前3個(gè)數(shù)
print(heapq.nsmallest(4,nums))
[42, 37, 23]
[-4, 1, 2, 2]
兩個(gè)函數(shù)都能狗解手一個(gè)關(guān)鍵字參數(shù),用于更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
import heapq
portInfo = [
{'name':'IBM','shares':100,'price':91.1},
{'name':'APPLE','shares':50,'price':543.22},
{'name':'FB','shares':200,'price':21.09},
{'name':'HPQ','shares':35,'price':31.75},
{'name':'YHOO','shares':45,'price':16.35},
{'name':'ACME','shares':75,'price':115.65},
]
expensive = heapq.nlargest(3,portInfo,key=lambda s:s['price'])
cheap = heapq.nsmallest(3,portInfo,key=lambda s : s['shares'])
print(expensive)
print(cheap)
# key = lambda s: s['price']
# print(key(portInfo[1]))
在上面的代碼對(duì)每個(gè)元素進(jìn)行對(duì)比的時(shí)候凉逛,會(huì)以price
的值進(jìn)行比較
[{'shares': 50, 'name': 'APPLE', 'price': 543.22}, {'shares': 75, 'name': 'ACME', 'price': 115.65}, {'shares': 100, 'name': 'IBM', 'price': 91.1}]
[{'shares': 35, 'name': 'HPQ', 'price': 31.75}, {'shares': 45, 'name': 'YHOO', 'price': 16.35}, {'shares': 50, 'name': 'APPLE', 'price': 543.22}]
如果你想在一個(gè)集合中查找最小或最大的N個(gè)元素性宏,并且N小于集合元素?cái)?shù)量,那么這些函數(shù)提供了很好的性能鱼炒。因?yàn)樵诘讓訉?shí)現(xiàn)里邊衔沼,首先會(huì)將集合數(shù)據(jù)進(jìn)行堆排序后放入一個(gè)列表中:
nums = [1,4,5,2,6,7,2,6,7,1,2,9]
heapq.heapify(nums)
print(nums)
注意:heapq.heapify(nums)
這個(gè)操作并沒(méi)有返回值
[1, 1, 2, 2, 2, 7, 5, 6, 7, 6, 4, 9]
堆數(shù)據(jù)結(jié)構(gòu)最重要的特征是heap[0]
永遠(yuǎn)是最小的元素,并且剩余的元素可以很容易通過(guò)調(diào)用heapq.heappop()
方法得到昔瞧,該方法會(huì)先將第一個(gè)元素彈出來(lái)指蚁,然后用下一個(gè)最小的元素來(lái)取代被彈出元素(成為最小的元素,這種操作時(shí)間復(fù)雜度為O(N),N是堆大小)
當(dāng)要查找的元素個(gè)數(shù)相對(duì)比較小的時(shí)候自晰,函數(shù)nlargest()
和nsmallest()
是很合適的凝化。如果你僅僅想查找唯一的最小或最大(N=1)的元素的話(huà),那么使用min()
和max()
函數(shù)會(huì)更快些酬荞。類(lèi)似的搓劫,如果N的大小和集合大小接近的時(shí)候,通常先排序這個(gè)集合然后在使用切片操作會(huì)更快點(diǎn)(sorted(items)[:N]
或者是sorted(items)[-N:]
)。
-
1.6 怎樣實(shí)現(xiàn)一個(gè)鍵對(duì)應(yīng)多個(gè)值得字典(也叫
multidict
)
解決方案:一個(gè)字典就是一個(gè)鍵對(duì)應(yīng)一個(gè)單值的映射混巧。如果你想要一個(gè)鍵映射多個(gè)值枪向,那么你就需要將這多個(gè)值放到另外的容器中,比如列表或者集合里邊咧党,你可以像下面這樣構(gòu)造這樣的字典
d = {
'a':[1,2,3],
'b':[4,5],
'c':[6,7,8,9]
}
e = {
'a':{1,2,3},
'b':{4,5},
'c':{6,7,8,9}
}
print(d)
print(e)
我發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象秘蛔,就這這兩個(gè)輸出語(yǔ)句同時(shí)打印的話(huà),輸出是有序的傍衡,兩個(gè)都是有序的深员,如果分開(kāi)只打印一句的話(huà),就是亂的蛙埂,當(dāng)然倦畅,列表的內(nèi)部是有序的
選擇使用列表還是集合取決于你的實(shí)際需求,如果你想保持元素的插入順序就應(yīng)該使用列表绣的,如果你想去掉重復(fù)元素就使用集合(并且不關(guān)心元素的順序問(wèn)題)
1.7字典排序
問(wèn)題:你想創(chuàng)建一個(gè)字典叠赐,并且在迭代或序列化這個(gè)字典的時(shí)候能夠控制元素的順序欲账。
??解決方案:為了控制一個(gè)字典中元素的順序,你可以使用collections
模塊中的OrderedDict
類(lèi)燎悍。在迭代操作的嘶吼它會(huì)保持元素被插入時(shí)的順序敬惦,示例如下:
from collections import OrderedDict
def order_dict():
d = OrderedDict()
d['bar'] = 2
d['grok'] = 4
d['foo'] = 1
d['spam'] = 3
for k in d:
print(k,d[k])
# for (k,v) in d.items():
# print(k,v)
order_dict()
bar 2
grok 4
foo 1
spam 3
- 當(dāng)你想要構(gòu)建一個(gè)將來(lái)需要序列化或編碼成其他格式的映射的時(shí)候,
OrderedDict
是非常有用的谈山。比如你想精確控制以JSON編碼后字段的順序俄删,你可以先使用OrderedDict
來(lái)構(gòu)建這樣的數(shù)據(jù)
import json
from collections import OrderedDict
d = OrderedDict()
d['bar'] = 2
d['grok'] = 4
d['foo'] = 1
d['spam'] = 3
print(d)
print(json.dumps(d))
>OrderedDict([('bar', 2), ('grok', 4), ('foo', 1), ('spam', 3)])
{"bar": 2, "grok": 4, "foo": 1, "spam": 3}
`OrderedDict`內(nèi)部維護(hù)著一個(gè)根據(jù)鍵插入順序排序的雙向鏈表。每次當(dāng)一個(gè)新的元素插入進(jìn)來(lái)的時(shí)候奏路,它會(huì)被放到鏈表的尾部畴椰。對(duì)于一個(gè)已經(jīng)存在的鍵的重復(fù)賦值不會(huì)改變鍵的順序。需要注意的是鸽粉,一個(gè) `OrderedDict`的大小是一個(gè)普通字典的兩倍斜脂,因?yàn)樗鼉?nèi)部維護(hù)著另一個(gè)鏈表。所以如果你需要構(gòu)建一個(gè)需要大量`OrderedDict`實(shí)例的數(shù)據(jù)結(jié)構(gòu)的時(shí)候(比如讀取100000行CSV數(shù)據(jù)到一個(gè)OrderedDict列表中去)触机,那么就得考慮一下`OrderedDict`帶來(lái)的好處與額外內(nèi)存消耗了帚戳。
##### 1.8字典的運(yùn)算
?怎么在數(shù)據(jù)字典中執(zhí)行一些計(jì)算操作(比如求最小值、最大值儡首、排序等等)?
prices = {
'ACME':45.23,
'APPL':612.78,
'IBM':205.55,
'HPQ':37.20,
'FB':10.75
}
print(prices)
print(min(zip(prices.values(),prices.keys())))
print(min(zip(prices.keys(),prices.values())))
為了對(duì)字典值執(zhí)行計(jì)算操作片任,通常需要使用`zip()`函數(shù)。蔬胯。对供。。關(guān)于zip(),未完待續(xù)氛濒。产场。。舞竿。
* 同樣的京景,可以結(jié)合`zip()` 和`sorted()`函數(shù)來(lái)排列字典
prices_sorted = sorted(zip(prices.values(),prices.keys()))
print(prices_sorted)
> [(10.75, 'FB'), (37.2, 'HPQ'), (45.23, 'ACME'), (205.55, 'IBM'), (612.78, 'APPL')]
* 需要注意的是`zip()`函數(shù)創(chuàng)建的是一個(gè)只能訪(fǎng)問(wèn)一次的迭代器。
prices_and_names = zip(prices.values(),prices.keys())
print(min(prices_and_names))
print(max(prices_and_names))#這里就會(huì)報(bào)錯(cuò)如下:
>(10.75, 'FB')
Traceback (most recent call last):
File "/Users/mudy/Documents/Python/Fishc/day01.py", line 160, in <module>
print(max(prices_and_names))
ValueError: max() arg is an empty sequence
* 1.9查找兩字典的相同點(diǎn)
  怎么在兩個(gè)字典中尋找相同點(diǎn)(比如相同的鍵骗奖,相同的值)
a = {
'x' : 1,
'y' : 2,
'z' : 3,
}
b = {
'w' : 10,
'x' : 11,
'y' : 2
}
print(a.keys() & b.keys())#AB同時(shí)存在的key
print(a.keys()-b.keys())#在A不在B里的
print(a.items()&b.items())#AB中同時(shí)存在的元素
>{'y', 'x'}
{'z'}
{('y', 2)}
你還可以這么的醋粟,假如你想以現(xiàn)有字典構(gòu)造一個(gè)排除幾個(gè)指定鍵的新字典。
c = {key:a[key] for key in a.keys()-{'z'}} #列表生成式
print(c)
>{'y': 2, 'x': 1}
##### 1.10刪除序列相同元素并保持順序
 怎樣在一個(gè)序列上面保持元素順序的同事消除重復(fù)的值重归。
關(guān)于`yield`可以看[這篇文章](https://www.oschina.net/translate/improve-your-python-yield-and-generators-explained)
`return隱含的意思是函數(shù)正將執(zhí)行代碼的控制權(quán)返回給函數(shù)被調(diào)用的地方。而"yield"的隱含意思是控制權(quán)的轉(zhuǎn)移是臨時(shí)和自愿的厦凤,我們的函數(shù)將來(lái)還會(huì)收回控制權(quán)鼻吮。`