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

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_bookbook_param

base_book.update(book_param)

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

如果只是單純的更新某個字典的信息的話泊柬,update() 方法顯然最合適椎镣。對于當(dāng)前需求的話,還是第一種方式更合適彬呻。

本文首發(fā)于公眾號「小小后端」,關(guān)注并回復(fù)「HMPython2018」獲取 2018 最新 Python 學(xué)習(xí)資源柄瑰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闸氮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子教沾,更是在濱河造成了極大的恐慌蒲跨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件授翻,死亡現(xiàn)場離奇詭異或悲,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)堪唐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門巡语,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淮菠,你說我怎么就攤上這事男公。” “怎么了合陵?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵枢赔,是天一觀的道長。 經(jīng)常有香客問我拥知,道長踏拜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任低剔,我火速辦了婚禮速梗,結(jié)果婚禮上肮塞,老公的妹妹穿的比我還像新娘。我一直安慰自己镀琉,他們只是感情好峦嗤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屋摔,像睡著了一般烁设。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钓试,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天装黑,我揣著相機(jī)與錄音,去河邊找鬼弓熏。 笑死恋谭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挽鞠。 我是一名探鬼主播疚颊,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼信认!你這毒婦竟也來了材义?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嫁赏,失蹤者是張志新(化名)和其女友劉穎其掂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潦蝇,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡款熬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了攘乒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贤牛。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖则酝,靈堂內(nèi)的尸體忽然破棺而出盔夜,到底是詐尸還是另有隱情,我是刑警寧澤堤魁,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布喂链,位于F島的核電站,受9級特大地震影響妥泉,放射性物質(zhì)發(fā)生泄漏椭微。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一盲链、第九天 我趴在偏房一處隱蔽的房頂上張望蝇率。 院中可真熱鬧迟杂,春花似錦、人聲如沸本慕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锅尘。三九已至监氢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間藤违,已是汗流浹背浪腐。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顿乒,地道東北人议街。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像璧榄,于是被迫代替她去往敵國和親特漩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容