作者:SeanCheney
鏈接:https://www.jianshu.com/p/b444cda10aa0
從中一部分覺得比較有用的記錄下來,
也有一些自己的理解
默認值賦值方法:
if key in some_dict:
value = some_dict[key]
else:
value = default_value
# dict.get方法相當於上面那個默認值方法
value = some_dict.get(key, default_value)
setdefault方法, 沒詳細看:
In [123]: words = ['apple', 'bat', 'bar', 'atom', 'book']
In [124]: by_letter = {}
In [125]: for word in words:
.....: letter = word[0]
.....: if letter not in by_letter:
.....: by_letter[letter] = [word]
.....: else:
.....: by_letter[letter].append(word)
.....:
In [126]: by_letter
Out[126]:
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
# 相當於下面setdefault
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
collections模塊有一個很有用的類,defaultdict,進一步簡化上面。
傳遞類型或函數以生成每個位置的默認值:
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)
列表、集合和字典推導式(好用):
# 它允許用戶方便的從一個集合過濾元素,形成列表,
# 在傳遞參數的過程中還可以修改元素。
strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
[x.upper() for x in strings if len(x) > 2]
Out[155]: ['BAT', 'CAR', 'DOVE', 'PYTHON']
用相似的方法,還可以推導集合和字典。字典的推導式如下所示:
dict_comp =
{key-expr : value-expr for value in collection if condition}
集合的推導式與列表很像,只不過用的是尖括號:
set_comp = {expr for value in collection if condition}
與列表推導式類似,集合與字典的推導也很方便,而且使代碼的讀寫都很容易。來看前面的字符串列表。假如我們只想要字符串的長度,用集合推導式的方法非常方便:
In [156]: unique_lengths = {len(x) for x in strings}
In [157]: unique_lengths
Out[157]: {1, 2, 3, 4, 6}
map函數可以進一步簡化:
In [158]: set(map(len, strings))
Out[158]: {1, 2, 3, 4, 6}
多層for循環
In [164]: some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
In [165]:
flattened = [x for tup in some_tuples for x in tup]
In [166]: flattened
Out[166]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
記住,for表達式的順序是與嵌套for循環的順序一樣(而不是列表推導式的順序):
flattened = []
for tup in some_tuples:
for x in tup:
flattened.append(x)
你可以有任意多級別的嵌套,但是如果你有兩三個以上的嵌套,你就應該考慮下代碼可讀性的問題了。分辨列表推導式的列表推導式中的語法也是很重要的:
In [167]: [[x for x in tup] for tup in some_tuples]
Out[167]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
這段代碼產生了一個列表的列表,而不是扁平化的只包含元素的列表。
函數相關
位置參數與關鍵參數
def params_practice(x, y, z=1.5):
print(x, y, z)
params_practice(y=1,x=2,z=3)
Out[167]: 2 1 3
params_practice(y=1,x=2)
Out[168]: 2 1 1.5
函數可以返回多個值,大概如下
def f():
a = 5
b = 6
c = 7
return {'a' : a, 'b' : b, 'c' : c}
處理字符格式
import re
states = [' Alabama ', 'Georgia!', 'Georgia',
'georgia', 'FlOrIda', 'south carolina##', 'West virginia?']
def clean_strings(str):
return [re.sub('[#!?]', '', x.strip()).title()
for x in str]
Out[169]: ['Alabama',
'Georgia',
'Georgia',
'Georgia',
'Florida',
'South Carolina',
'West Virginia']
生成器
能以一種一致的方式對序列進行迭代(比如列表中的對象或文件中的行)是Python的一個重要特點。這是通過一種叫做迭代器協議(iterator protocol,它是一種使對象可迭代的通用方式)的方式實現的,一個原生的使對象可迭代的方法。比如說,對字典進行迭代可以得到其所有的鍵:
In [180]: some_dict = {'a': 1, 'b': 2, 'c': 3}
In [181]: for key in some_dict:
.....: print(key)
a
b
c
當你編寫for key in some_dict時,Python解釋器首先會嘗試從some_dict創建一個迭代器:
In [182]: dict_iterator = iter(some_dict)
In [183]: dict_iterator
Out[183]: <dict_keyiterator at 0x7fbbd5a9f908>
迭代器是一種特殊對象,它可以在諸如for循環之類的上下文中向Python解釋器輸送對象。大部分能接受列表之類的對象的方法也都可以接受任何可迭代對象。比如min、max、sum等內置方法以及list、tuple等類型構造器:
In [184]: list(dict_iterator)
Out[184]: ['a', 'b', 'c']
生成器(generator)是構造新的可迭代對象的一種簡單方式。一般的函數執行之後只會返回單個值,而生成器則是以延遲的方式返回一個值序列,即每返回一個值之後暫停,直到下一個值被請求時再繼續。要創建一個生成器,只需將函數中的return替換爲yeild即可:
def squares(n=10):
print('Generating squares from 1 to {0}'.format(n ** 2))
for i in range(1, n + 1):
yield i ** 2
調用該生成器時,沒有任何代碼會被立即執行:
In [186]: gen = squares()
In [187]: gen
Out[187]: <generator object squares at 0x7fbbd5ab4570>
直到你從該生成器中請求元素時,它纔會開始執行其代碼:
In [188]: for x in gen:
.....: print(x, end=' ')
Generating squares from 1 to 100
1 4 9 16 25 36 49 64 81 100
生成器表達式
另一種更簡潔的構造生成器的方法是使用生成器表達式(generator expression)。這是一種類似於列表、字典、集合推導式的生成器。其創建方式爲,把列表推導式兩端的方括號改成圓括號:
In [189]: gen = (x ** 2 for x in range(100))
In [190]: gen
Out[190]: <generator object <genexpr> at 0x7fbbd5ab29e8>
它跟下面這個冗長得多的生成器是完全等價的:
def _make_gen():
for x in range(100):
yield x ** 2
gen = _make_gen()
生成器表達式也可以取代列表推導式,作爲函數參數:
In [191]: sum(x ** 2 for x in range(100))
Out[191]: 328350
In [192]: dict((i, i **2) for i in range(5))
Out[192]: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}