Python中使用字典的幾個小技巧

Python中使用字典的幾個小技巧

來自專欄小小後端

1 解包

所謂解包,就是將字典通過 ** 操作符轉為 Key=Value 的形式,這種形式可以直接傳給函數作為關鍵字參數。

說說適用的幾種情況。

1.1 搜索拼接條件

當應用中使用類似 SQLAlchemy 的 ORM 形式讀取數據的時候,不同搜索條件,傳入給 ORM 的搜索參數也隨之改變。

下面是圖書表的部分數據(只展示了部分欄位)

+----+---------------+-------------------------+-------+| id | category_name | book_name | price |+----+---------------+-------------------------+-------+| 1 | 人文社科 | 人類簡史 | 42.90 || 2 | 人文社科 | 世界簡史 | 25.50 || 3 | 經濟管理 | 極致產品 | 37.00 || 4 | 經濟管理 | 史蒂夫·喬布斯傳 | 44.20 || 5 | 經濟管理 | 影響力 | 41.20 |+----+---------------+-------------------------+-------+

搜索時,我們會以這樣的形式執行查詢方法

books = Book.query.filter_by(id=1, book_name=影響力).all()

但是由於傳入參數會根據搜索條件的變化而變化,無法直接寫出有哪些參數,這個時候就可以使用字典解包

condition = {}if book_id: condition[id] = idif book_name: condition[name] = book_namebooks = Book.query.filter_by(**condition).all()

這樣就 OK 了

1.2 方法參數太多,為代碼美觀使用

new_book = Book(category_name=文學小說, book_name=解憂雜貨店, price=28.8, ...)db.session.add(new_book)

改成這樣的話,美觀一些

book_param = {category_name: 文學小說, book_name: 解憂雜貨店, price: 28.8, ...}new_book = Book(**book_param)db.session.add(new_book)

並且,在上述新增圖書過程中,都會對提交的參數進行校驗,而校驗方法返回的結果(也就是 book_param 和其它信息)一般也都是字典,所以使用字典解包的方式更符合實際場景。

總之,適當使用字典解包對方法進行傳參,可以讓我們的代碼更靈活。

2 setdefault() 的使用

先看下這個方法怎麼使用

dict.setdefault(key, default=None)

如果字典中包含有給定鍵,則返回該鍵對應的值,否則返回為該鍵設置的值。

很多時候我們需要對列表根據元素的某個 key 轉化成一個包含列表的字典。比如,上面的數據中,我希望得到一個字典,字典的 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)

當然,這樣寫是正確的,能得到預期結果

{ "人文社科": [{ "id": 1, "category_name": "人文社科", "book_name": "人類簡史", "price": 42.9 }, { "id": 2, "category_name": "人文社科", "book_name": "世界簡史", "price": 25.5 }], "經濟管理": [{ "id": 3, "category_name": "經濟管理", "book_name": "極致產品", "price": 37.0 }, { "id": 4, "category_name": "經濟管理", "book_name": "史蒂夫·喬布斯傳", "price": 44.2 }, { "id": 5, "category_name": "經濟管理", "book_name": "影響力", "price": 41.2 }]}

但是如果使用字典的 setdefault() 方法話,可以少寫幾行代碼,看起來也優雅一些

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 的對應值# 理解為更新某個字典應該更合適>>> a.update(b)>>> a{name: y, age: 13}

有時我們碰到合併字典的情況也不少。比如,我們準備根據一本書的基本信息創建一本新書

# to_dict 將 ORM 對象轉為字典,是自定義的,理解意思就好base_book = Book.query.filter_by(id=1).first().to_dict()# 提交的參數需要校驗,校驗成功後返回值包含 book_param ,內容和下面類似book_param = {book_name: 國家寶藏, price: 55.60}# 同時需要更新新書的創建時間和更新時間time_param = {created_at: current_time, updated_at: current_time}# 新增書籍new_book = Book(**{**base_book, **book_param, **time_param})db.session.add(new_book)

當然,如果只是合併兩個字典的話,也可以使用 update() 方法。

假設我們只需要合併 base_book 和 book_param

base_book.update(book_param)

這也可以工作,不過要注意,這樣會修改 base_book 中的值。

如果只是單純的更新某個字典的信息的話,update() 方法顯然最合適。對於當前需求的話,還是第一種方式更合適。

本文首發於微信公眾號「小小後端」。


推薦閱讀:

「互聯網+」如何為工業插上新翅膀
未來,燈照亮之處,有更優的5G網路
美圖手機為什麼可以長盛不衰?
科技界的流量王與帶貨王是怎樣一群人? | 脈訊微博大號榜單
看了很多連環殺手的案例,都在幾十年前。現代科技先進,網路發達,監控普遍,很難出現連環殺手了吧?

TAG:Python | 計算機科學 | 科技 |