一、一個包含N個元素的字元串、元組、序列、以及任何可疊代對象均可以拆分成N個單獨的“變量”
1.字元串的拆分
1 #字元串
2 In [10]: s="abdefg"
3 In [11]: o, p, q, x, y, z =s4 In [12]: q5 Out[12]: 'd'
6 In [13]: x7 Out[13]: 'e'
8 In [14]: z9 Out[14]: 'g'
2.清單、元組、集合和可疊代對象的拆分
1 list_l = [1,2,3,4]2
3 In [16]: tuple_l = [5,6,7,8]4
5 In [17]: a,b,c,d =list_l6
7 In [18]: b8 Out[18]: 2
9
10 In [19]: c11 Out[19]: 3
12
13 In [20]: d14 Out[20]: 4
15
16 In [21]: m,n,o,p =tuple_l17
18 In [22]: o19 Out[22]: 7
20
21 In [23]: p22 Out[23]: 8
23
24
25 d={'k1':'v1','k2':'v2'}26
27 In [2]: d28 Out[2]: {'k1': 'v1', 'k2': 'v2'}29
30 In [3]: key1,key2 =d.keys()31
32 In [4]: key133 Out[4]: 'k2'
34
35 In [5]: key236 Out[5]: 'k1'
一個綜合的例子:
1 In [11]: data = [1,2,[3,4,6],(7,8,9),{'k1':'v1','k2':2}]2 In [12]: a,b,li,tup,dic =data3 In [13]: a4 Out[13]: 1
5 In [14]: b6 Out[14]: 2
7 In [15]: tup8 Out[15]: (7, 8, 9)9 In [16]: dic10 Out[16]: {'k1': 'v1', 'k2': 2}11 In [17]: li12 Out[17]: [3, 4, 6]
問題1:如果想丢棄分解後的一些無用值怎麼辦?可以使用用不到的變量名"_"進行分割:
1 l=['money','money','no use','nouse','money']2 In [19]: a,b,_,_,e=l3 In [20]: print(a,b)4 money money5 In [21]: print(a,b,e)6 money money money
問題2:如果一個可疊代對象比較長,且大于要分割的數目怎麼辦?"*表達式"就該發揮作用了
l=range(1,100)
In [24]: len(l)
Out[24]: 99In [25]: first,*p,last =l #p是一個清單[2,...,98]
In [26]: print(first,len(p),last)1 97 99
In [1]: l=range(1,100)
In [2]: *q,m,n = l
In [3]: print (len(q),m,n) #q是一個清單[1,...,96]
97 98 99
In [4]: x,y,*z=l
In [5]: print(x,y,len(z))
1 2 97
同樣的,“*_”也可以作為看可以丢棄的無用的變量名
In [11]: l=range(1,100)
In [12]: first,*_,end = l
In [13]: print(first,end)
1 99
二、python标準庫collections子產品的常見應用
1. deque類,優點:可以在兩端執行添加和彈出,并且效率更高
1 from collections importdeque2 #建立一個總長度為5的deque對象
3 #預設maxlen=None,無限長度
4 dq = deque(maxlen=5)5 print(dq)6 #out:deque([], maxlen=5)
7 #append、appendleft方法
8 dq.append(1)9 print(dq)10 #out:deque([1], maxlen=5)
11 dq.appendleft(2)12 print(dq)13 #out:deque([2, 1], maxlen=5)
14 #插入序列清單、元組都可以
15 dq.extend([5,6])16 print(dq)17 #out:deque([2, 1, 5, 6], maxlen=5)
18 dq.extendleft([7,8,9])19 print(dq)20 #out:deque([9, 8, 7, 2, 1], maxlen=5)
21 #從末尾pop出來一個元素:1
22 dq.pop()23 print(dq)24 #out:deque([9, 8, 7, 2], maxlen=5)
25 #從開頭出pop出來一個元素:9
26 dq.popleft()27 print(dq)28 #out:deque([8, 7, 2], maxlen=5)
29 #複制一份,互相獨立
30 dq_copy =dq.copy()31 print(dq,dq_copy)32 #out:deque([8, 7, 2], maxlen=5) deque([8, 7, 2], maxlen=5)
33 #dq.index(x)傳回x在dq中的索引
34 print(dq.index(7))35 #out:1
36 #dq.count(x)傳回dq中x的數目
37 print(dq.count(7))38 #out:1
39 #傳回容量
40 print(dq.maxlen)41 #out:5
42 #dq.insert(index,x) 在index處插入x
43 dq.insert(0,110)44 print(dq)45 #out:deque([110, 8, 7, 2], maxlen=5)
46 #dq.remove(x)從dq中移除x
47 try:48 dq.remove(99)49 exceptException as e:50 print(e)51 #out:deque.remove(x): x not in deque
52 #dq.reverse(),轉置
53 dq.reverse()54 print(dq)55 #out:deque([2, 7, 8, 110], maxlen=5)
56 for i indq:57 print(i)58 '''
59 260 761 862 11063 '''
64 #清空所有元素
65 dq.clear()66 print(dq)67 #deque([], maxlen=5)
68 #^_^ over
2. defaultdict類,定義一個字典對象.優點:非常容易的實作一Key多Vallue的字典
例如;d={'a':[1,2,3,4],'b':[5,7]} ,s={'a':{2,3,4},'b':{4,5}}
執行個體化:d=defaultdict(list|set) 清單、集合根據需要設定,效果如上.(元素去重用set,保持元素順序用list)
1 '''
2 default一大優點就是建立執行個體的同時就已經初始化了一個可能會用到的值例如下列中的d1['a']、d2['a']3 '''
4 In [5]: d1=dict()5 In [6]: from collections importdefaultdict6 In [7]: d2=defaultdict(list)7 In [8]: print(d1['a'])8 ---------------------------------------------------------------------------
9 KeyError Traceback (most recent call last)10 in ()11 ----> 1 print(d1['a'])12 KeyError: 'a'
13 In [9]: print(d2['a'])14 []
看一個我遇到的使用defaultdict的比較好的例子:
1 from collections importdefaultdict2 '''完整代碼不貼了,用一個清單簡化一下當時我的需求:
3 計算下面清單中的每一個元素split後的第二個元素是y的個數(即:string.split()[1]=='y'),并且與string.split()[0]一 一對應.4 '''
5
6 l=['a y','a n','a n','a n','a y','a y','a y''a y','b n','b n','b y','b y','b n','b y']7
8 d=defaultdict(list)9 for i inl:10 if i.split()[1]=='y':11 d[i.split()[0]].append(1) #這一步完全忽視i.split()[0]是什麼東西,就是幹,換了dict()肯定要先定義一個key了。。。比如d=dict();d['a']=[];12 for k,v ind.items():13 print('{}:{}次'.format(k,len(v)))
--------------------------------------------
b:3次 #直到這裡才知道都是麼鬼,幾個鬼
a:3次
3.OrderedDict類,看名字就跟順序有關,是的,它的作用是讓存入字典的k,v對保持插入時的順序(資料量較大時需要考慮性能)
1 In [10]: from collections importOrderedDict2
3 In [11]: d=OrderedDict()4
5 In [12]: d['a']=1
6
7 In [13]: d['b']=2
8
9 In [14]: d['c']=3
10
11 In [15]: d['d']=4
12
13 In [16]: for k ind:14 ....: print(k,d[k])15 ....:16 ------------------------------------
17 a 1
18 b 2
19 c 3
20 d 4
4.Counter類.能夠簡單快捷的傳回序列中出現次數最多的元素和個數.
1 >>> l =[]2 >>> for i in range(1,20):3 ... l.append(chr(random.randint(97,100))) #這裡我們并不知道都随機生成了什麼字元清單,但是大緻知道是[a-d]4...5 >>> list_count = Counter(l) #執行個體Counter對象
6 >>> top_three = list_count.most_common(3) #取出啊前三個出現次數最多的元素
7 >>> print(top_three)8 [('a', 8), ('d', 4), ('b', 4)]
假如我們知道裡面有一個字元(比如'a')出現了很多次,想要得到具體多少次呢?
>>> list_count['a']8
>>> list_count['b']4
>>> list_count['d']4
>>> list_count['c']3
>>> print(list_count['e'])
0>>> print(l)
['a', 'd', 'a', 'd', 'a', 'b', 'a', 'a', 'd', 'b', 'd', 'a', 'a', 'a', 'c', 'c', 'c', 'b', 'b']
操作跟字典真是太像了,沒錯看一下Counter類的定義,以及其它用法
classCounter(dict):#沒錯,繼承自字典。。。'''Dict subclass for counting hashable items. Sometimes called a bag
or multiset. Elements are stored as dictionary keys and their counts
are stored as dictionary values.
>>> c = Counter('abcdeabcdabcaba') # count elements from a string
>>> c.most_common(3) # three most common elements
[('a', 5), ('b', 4), ('c', 3)]
>>> sorted(c) # list all unique elements
['a', 'b', 'c', 'd', 'e']
>>> ''.join(sorted(c.elements())) # list elements with repetitions
'aaaaabbbbcccdde'
>>> sum(c.values()) # total of all counts
15
>>> c['a'] # count of letter 'a'
5
>>> for elem in 'shazam': # update counts from an iterable
... c[elem] += 1 # by adding 1 to each element's count
>>> c['a'] # now there are seven 'a'
7
>>> del c['b'] # remove all 'b'
>>> c['b'] # now there are zero 'b'
>>> d = Counter('simsalabim') # make another counter
>>> c.update(d) # add in the second counter
>>> c['a'] # now there are nine 'a'
9
>>> c.clear() # empty the counter
>>> c
Counter()
Note: If a count is set to zero or reduced to zero, it will remain
in the counter until the entry is deleted or the counter is cleared:
>>> c = Counter('aaabbc')
>>> c['b'] -= 2 # reduce the count of 'b' by two
>>> c.most_common() # 'b' is still in, but its count is zero
[('a', 3), ('c', 1), ('b', 0)]'''
三、通過公共鍵,對字典清單排序(sorted),最大值(max),最小值(min)
方法-1:使用operator.itemgetter
from operator importitemgetter
l=[
{'name': '股票1','num': '000001','price': 13.7},
{'name': '股票2','num': '000002','price': 15.7},
{'name': '股票4','num': '000004','price': 16.7},
{'name': '股票3','num': '000003','price': 10.7}
]print(l)
sort_by_bum= sorted(l,key=itemgetter('num'))
sort_by_price= sorted(l,key=itemgetter('price'))print(sort_by_bum)print(sort_by_price)---------------------------[{'name': '股票1', 'num': '000001', 'price': 13.7}, {'name': '股票2', 'num': '000002', 'price': 15.7}, {'name': '股票4', 'num': '000004', 'price': 16.7}, {'name': '股票3', 'num': '000003', 'price': 10.7}]
[{'name': '股票1', 'num': '000001', 'price': 13.7}, {'name': '股票2', 'num': '000002', 'price': 15.7}, {'name': '股票3', 'num': '000003', 'price': 10.7}, {'name': '股票4', 'num': '000004', 'price': 16.7}]
[{'name': '股票3', 'num': '000003', 'price': 10.7}, {'name': '股票1', 'num': '000001', 'price': 13.7}, {'name': '股票2', 'num': '000002', 'price': 15.7}, {'name': '股票4', 'num': '000004', 'price': 16.7}]
---------------------------------------------------
from operator import itemgetter
l = [
{'name': '股票1','num': '000001','price': 13.7},
{'name': '股票2','num': '000002','price': 15.7},
{'name': '股票3','num': '000003','price': 16.7},
{'name': '股票3','num': '000003','price': 10.7}
]
print(l)
sort_by_num_price = sorted(l,key=itemgetter('num','price'))
print(sort_by_num_price)---------------------------
[{'price': 13.7, 'num': '000001', 'name': '股票1'}, {'price': 15.7, 'num': '000002', 'name': '股票2'}, {'price': 16.7, 'num': '000003', 'name': '股票4'}, {'price': 10.7, 'num': '000003', 'name': '股票3'}]
[{'price': 13.7, 'num': '000001', 'name': '股票1'}, {'price': 15.7, 'num': '000002', 'name': '股票2'}, {'price': 10.7, 'num': '000003', 'name': '股票3'}, {'price': 16.7, 'num': '000003', 'name': '股票4'}]
方法-2:差別僅僅在于key後面函數的實作方式.無論lambda,itemgetter都是定義了一個func
func(x) = lambda x:x['num'] ==>return x['num']
func = itemgetter('num') func(r)==>return r['num']
#使用匿名函數lambdal=[
{'name': '股票1','num': '000001','price': 13.7},
{'name': '股票2','num': '000002','price': 15.7},
{'name': '股票4','num': '000004','price': 16.7},
{'name': '股票3','num': '000003','price': 10.7}
]print(l)
sort_by_bum= sorted(l,key=lambda x:x['num'])
sort_by_price= sorted(l,key=lambda x:x['price'])print(sort_by_bum)print(sort_by_price)-------------------------[{'name': '股票1', 'num': '000001', 'price': 13.7}, {'name': '股票2', 'num': '000002', 'price': 15.7}, {'name': '股票4', 'num': '000004', 'price': 16.7}, {'name': '股票3', 'num': '000003', 'price': 10.7}]
[{'name': '股票1', 'num': '000001', 'price': 13.7}, {'name': '股票2', 'num': '000002', 'price': 15.7}, {'name': '股票3', 'num': '000003', 'price': 10.7}, {'name': '股票4', 'num': '000004', 'price': 16.7}]
[{'name': '股票3', 'num': '000003', 'price': 10.7}, {'name': '股票1', 'num': '000001', 'price': 13.7}, {'name': '股票2', 'num': '000002', 'price': 15.7}, {'name': '股票4', 'num': '000004', 'price': 16.7}]
---------------------------------------------------分割線--l = [
{'name': '股票1','num': '000001','price': 13.7},
{'name': '股票2','num': '000002','price': 15.7},
{'name': '股票3','num': '000003','price': 16.7},
{'name': '股票3','num': '000003','price': 10.7}
]
print(l)sort_by_num_price = sorted(l,key=lambda x:(x['num'],x['price']))print(sort_by_num_price)
---------------------------
[{'price': 13.7, 'num': '000001', 'name': '股票1'}, {'price': 15.7, 'num': '000002', 'name': '股票2'}, {'price': 16.7, 'num': '000003', 'name': '股票4'}, {'price': 10.7, 'num': '000003', 'name': '股票3'}]
[{'price': 13.7, 'num': '000001', 'name': '股票1'}, {'price': 15.7, 'num': '000002', 'name': '股票2'}, {'price': 10.7, 'num': '000003', 'name': '股票3'}, {'price': 16.7, 'num': '000003', 'name': '股票4'}]
最大值,最小值,max,min
from operator importitemgetter
l=[
{'name': '股票1','num': '000001','price': 13.7},
{'name': '股票2','num': '000002','price': 15.7},
{'name': '股票4','num': '000004','price': 16.7},
{'name': '股票3','num': '000003','price': 10.7}
]max= max(l,key=itemgetter('price'))
min= min(l,key=itemgetter('price'))print(max)print(min)-----------------------------{'num': '000004', 'price': 16.7, 'name': '股票4'}
{'num': '000003', 'price': 10.7, 'name': '股票3'}
四.高階函數map/filter/sorted
class map(object)
| map(func, *iterables) --> map object
| Make an iterator that computes the function using arguments from
| each of the iterables. Stops when the shortest iterable is exhausted.
簡單解釋下,map有需要兩個參數func和iterables.可以這麼了解,func是你根據需求編寫的一個函數,iterables是你需要操作的一個可疊代對象,他們的傳回值是一個iterator(疊代器),有關疊代器的概念這裡不多講,不過暫時可以簡單的記住疊代器可以通過list(iterator)或者set(iterator)生成一個清單或者集合.
舉個比較經典的例子吧,把一個數列a = [1,2,3,3,4,5,6]中的所有元素平方後生成一個新的數列b:
>>> a = [1,2,3,4,5,67]>>> deffunc(x):
...return x*x
...>>> b=list(map(func,a))>>>b
[1, 4, 9, 16, 25, 4489]>>>
在這個例子中,假設你不清楚map用法也完全可以得到我們想要的結果b,不過那樣的話你是不是至少用一個for循環呢,多謝幾行代碼呢?其實多寫幾行代碼倒是沒有什麼,重點使用map起碼能夠給我們的代碼增添一點點點的亮點。
class filter(object)
| filter(function or None, iterable) --> filter object
| Return an iterator yielding those items of iterable for which function(item)
| is true. If function is None, return the items that are true.
跟map一樣需要兩個參數func和可疊代對象,在filter執行過程中把iterable中的每一個元素疊代到func中,如果執行結果為真的把目前元素添加到疊代器中,當所有元素執行完後,傳回疊代器.
看例子:
a=[4,5,6,7,8,9,0]>>> defdayu_5(x):
...if x>5:
...returnTrue>>>list(filter(dayu_5,a))
[6, 7, 8, 9]
sorted(iterable, key=None, reverse=False)
Return a new list containing all items from the iterable in ascending order.
傳回一個包含了所有可疊代對象,并且按照升序排列的一個新的清單
看例子:
>>> l=[2,34,5,61,2,4,6,89]>>>sorted(l)
[-89, -6, 2, 2, 4, 5, 34, 61]>>> sorted(l,key=lambdax:abs(x))
[2, 2, 4, 5, -6, 34, 61, -89]>>> sorted(l,key=lambda x:abs(x),reverse=True)
[-89, 61, 34, -6, 5, 4, 2, 2]
#三個例子分别使用了sorted的預設排序,key自定義排序,以及reverse翻轉的功能.
key其實表示的一個函數,接着看下面的例子:
>>> def ff(x):
... return abs(x)
>>> sorted(l,key=ff,reverse=False)
[2, 2, 4, 5, -6, 34, 61, -89]
可以看到效果是一樣的
五 heapq子產品
nlargest()和nsmallest()
Help on function nlargest in module heapq:
nlargest(n, iterable, key=None)
Find the n largest elements in a dataset.
Equivalent to: sorted(iterable, key=key, reverse=True)[:n]
通過help函數可以看到,heapq.nlargest()作用為從可疊代對象iterable中,依據key的定義取出最大的n個值,其作用等于sorted(iterable, key=key, reverse=True)[:n]表達式
1 >>> l2=[(10,2),(9,5),(8,10),(7,6),(6,1)]2 >>> l = [12,34,22,45,678,89,100,232,23]3 >>>help(heapq.nlargest)4
5 >>> l = [12,34,22,45,678,89,100,232,23]6 >>> heapq.nlargest(5,l)7 [678, 232, 100, 89, 45]8 >>> l2=[(10,2),(9,5),(8,10),(7,6),(6,1)]9 >>> heapq.nlargest(3,l2,key=lambda x:x[1])10 [(8, 10), (7, 6), (9, 5)]11 >>>
12 >>> sorted(l,reverse=True)[:5]13 [678, 232, 100, 89, 45]14 >>>
Help on function nsmallest in module heapq:
nsmallest(n, iterable, key=None)
Find the n smallest elements in a dataset.
Equivalent to: sorted(iterable, key=key)[:n]
通過help幫助可以發現nsmallest()剛好和nlargest()作用相反
1 >>> heapq.nsmallest(5,l)2 [12, 22, 23, 34, 45]3 >>> sorted(l)[:5]4 [12, 22, 23, 34, 45]5 >>> heapq.nsmallest(3,l2,key=lambda x:x[1])6 [(6, 1), (10, 2), (9, 5)]7 >>>
六 去除序列中的重複項并保持順序不變
通常情況下我們經常用set給序列排序,但是往往原來的順序會發生改變,如下面例子
>>> l=[]>>> for i in range(10):
... l.append(random.randint(1,4))
...>>>list(set(l))
[1, 2, 3, 4]>>>
待續。。