1 解包
所謂解包容贝,就是將字典通過 ** 操作符轉(zhuǎn)為 Key=Value 的形式自脯,這種形式可以直接傳給函數(shù)作為關(guān)鍵字參數(shù)。
說說適用的幾種情況斤富。
1.1 搜索拼接條件
當(dāng)應(yīng)用中使用類似 SQLAlchemy 的 ORM 形式讀取數(shù)據(jù)的時候膏潮,不同搜索條件,傳入給 ORM 的搜索參數(shù)也隨之改變满力。
下面是圖書表的部分?jǐn)?shù)據(jù)(只展示了部分字段)
+----+---------------+-------------------------+-------+
| id | category_name | book_name | price |
+----+---------------+-------------------------+-------+
| 1 | 人文社科 | 人類簡史 | 42.90 |
| 2 | 人文社科 | 世界簡史 | 25.50 |
| 3 | 經(jīng)濟(jì)管理 | 極致產(chǎn)品 | 37.00 |
| 4 | 經(jīng)濟(jì)管理 | 史蒂夫·喬布斯傳 | 44.20 |
| 5 | 經(jīng)濟(jì)管理 | 影響力 | 41.20 |
+----+---------------+-------------------------+-------+
搜索時焕参,我們會以這樣的形式執(zhí)行查詢方法
books = Book.query.filter_by(id=1, book_name='影響力').all()
但是由于傳入?yún)?shù)會根據(jù)搜索條件的變化而變化,無法直接寫出有哪些參數(shù)油额,這個時候就可以使用字典解包
condition = {}
if book_id:
condition['id'] = id
if book_name:
condition['name'] = book_name
books = Book.query.filter_by(**condition).all()
這樣就 OK 了
1.2 方法參數(shù)太多叠纷,為代碼美觀使用
new_book = Book(category_name='文學(xué)小說', book_name='解憂雜貨店', price=28.8,
...)
db.session.add(new_book)
改成這樣的話,美觀一些
book_param = {'category_name': '文學(xué)小說', 'book_name': '解憂雜貨店', 'price': 28.8,
...}
new_book = Book(**book_param)
db.session.add(new_book)
并且潦嘶,在上述新增圖書過程中涩嚣,都會對提交的參數(shù)進(jìn)行校驗(yàn),而校驗(yàn)方法返回的結(jié)果(也就是 book_param
和其它信息)一般也都是字典掂僵,所以使用字典解包的方式更符合實(shí)際場景航厚。
總之,適當(dāng)使用字典解包對方法進(jìn)行傳參锰蓬,可以讓我們的代碼更靈活幔睬。
2 setdefault() 的使用
先看下這個方法怎么使用
dict.setdefault(key, default=None)
如果字典中包含有給定鍵,則返回該鍵對應(yīng)的值芹扭,否則返回為該鍵設(shè)置的值溪窒。
很多時候我們需要對列表根據(jù)元素的某個 key 轉(zhuǎn)化成一個包含列表的字典。比如冯勉,上面的數(shù)據(jù)中澈蚌,我希望得到一個字典,字典的 key 是圖書分類灼狰,value 是屬于該分類的圖書列表宛瞄。我們通常會這樣寫
books_dict = {}
for book in book_list:
if book['category_name'] not in books_dict.keys():
books_dict[book['category_name']] = []
books_dict[book['category_name']].append(book)
當(dāng)然,這樣寫是正確的交胚,能得到預(yù)期結(jié)果
{
"人文社科": [{
"id": 1,
"category_name": "人文社科",
"book_name": "人類簡史",
"price": 42.9
}, {
"id": 2,
"category_name": "人文社科",
"book_name": "世界簡史",
"price": 25.5
}],
"經(jīng)濟(jì)管理": [{
"id": 3,
"category_name": "經(jīng)濟(jì)管理",
"book_name": "極致產(chǎn)品",
"price": 37.0
}, {
"id": 4,
"category_name": "經(jīng)濟(jì)管理",
"book_name": "史蒂夫·喬布斯傳",
"price": 44.2
}, {
"id": 5,
"category_name": "經(jīng)濟(jì)管理",
"book_name": "影響力",
"price": 41.2
}]
}
但是如果使用字典的 setdefault() 方法話份汗,可以少寫幾行代碼,看起來也優(yōu)雅一些
books_dict = {}
for book in book_list:
books_dict.setdefault(book['category_name'], []).append(book)
3 字典合并
常用的合并方式
# new_dict = {**dict1, **dict2, ...}
# 合并多個字典蝴簇,如果字典中存在相同的 key 的話杯活,后面的會覆蓋掉前面的
# 比如 dict2 會覆蓋 dict1 中的 key 相同的值
>>> a = {'name': 'x', 'age': 13}
>>> b = {'name': 'y'}
>>> c = {**a, **b}
>>> c
{'name': 'y', 'age': 13}
# dict1.update(dict2)
# 合并兩個字典,如果字典中存在相同的 key 的話熬词,dict2 會覆蓋 dict1 的對應(yīng)值
# 理解為更新某個字典應(yīng)該更合適
>>> a.update(b)
>>> a
{'name': 'y', 'age': 13}
有時我們碰到合并字典的情況也不少旁钧。比如吸重,我們準(zhǔn)備根據(jù)一本書的基本信息創(chuàng)建一本新書
# to_dict 將 ORM 對象轉(zhuǎn)為字典,是自定義的歪今,理解意思就好
base_book = Book.query.filter_by(id=1).first().to_dict()
# 提交的參數(shù)需要校驗(yàn)嚎幸,校驗(yàn)成功后返回值包含 book_param ,內(nèi)容和下面類似
book_param = {'book_name': '國家寶藏', 'price': 55.60}
# 同時需要更新新書的創(chuàng)建時間和更新時間
time_param = {'created_at': current_time, 'updated_at': current_time}
# 新增書籍
new_book = Book(**{**base_book, **book_param, **time_param})
db.session.add(new_book)
當(dāng)然寄猩,如果只是合并兩個字典的話嫉晶,也可以使用 update() 方法。
假設(shè)我們只需要合并 base_book
和 book_param
base_book.update(book_param)
這也可以工作田篇,不過要注意替废,這樣會修改 base_book
中的值。
如果只是單純的更新某個字典的信息的話泊柬,update() 方法顯然最合適椎镣。對于當(dāng)前需求的話,還是第一種方式更合適彬呻。
本文首發(fā)于公眾號「小小后端」,關(guān)注并回復(fù)「HMPython2018」獲取 2018 最新 Python 學(xué)習(xí)資源柄瑰。