停止這樣使用 Python 字典!
如果你是個(gè)初學(xué)者,或者寫代碼有一段時(shí)間了,需要好好看一下你是否也會(huì)一樣,像接下來的文章一樣,錯(cuò)誤使用 Python 字典。如果你也是一個(gè)資深玩家,可以一起探討!~
不瞞你說,就連我也……但我從錯(cuò)誤中吸取了教訓(xùn),并改正了。所以今天特地總結(jié)了幾個(gè)常見錯(cuò)誤,也來阻止你。
錯(cuò)誤#1
檢查密鑰是否存在的錯(cuò)誤方法
有時(shí)人們會(huì)這樣做來檢查密鑰是否存在:
my_dict = {"name": "Kiran", "age": 24}
if "name" in my_dict:
print(my_dict["name"])
else:
print("No name found")
我知道這可行……但我覺得沒必要。我們可以用更好的方法來做這件事。
我們可以使用.get():
my_dict = {"name": "Kiran", "age": 24}
print(my_dict.get("name", "No name found"))
現(xiàn)在,我們的代碼看起來更簡潔了。我們不需要額外的 if-else 檢查。
錯(cuò)誤 #2
我們?cè)?jīng)錯(cuò)誤地循環(huán)遍歷鍵和值
許多人習(xí)慣用這樣的循環(huán):
my_dict = {"a": 1, "b": 2, "c": 3}
for key in my_dict:
print(key, my_dict[key])
我知道……這個(gè)方法可行。但我們可以用更好的方法。我們可以用.items()這個(gè)來代替。
for key, value in my_dict.items():
print(key, value)
現(xiàn)在...如果我們進(jìn)行一些字典查找,這將更具可讀性并且更快。
錯(cuò)誤#3
有時(shí)我們使用的update()方式是錯(cuò)誤的
有些初學(xué)者是這樣合并詞典的:
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
dict1.update(dict2)
print(dict1)
這肯定會(huì)起作用......但它會(huì)修改 dict1。
除此之外,我們可以使用字典解包:
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
new_dict = {**dict1, **dict2}
print(new_dict) # {'a': 1, 'b': 3, 'c': 4}
這將創(chuàng)建一個(gè)新的詞典。它更安全,因?yàn)椴粫?huì)對(duì)原始詞典造成意外修改
錯(cuò)誤#4
我們可以defaultdict在不需要的時(shí)候使用它
有時(shí)...人們過度使用defaultdict。
例如:
from collections import defaultdict
my_dict = defaultdict(int)
my_dict["a"] += 1 # 有效,但有必要嗎?
我知道……這可行。但是……這真的有必要嗎?我們可以使用更好的方法,例如:
my_dict = {}
my_dict["a"] = my_dict.get("a", 0) + 1
這將使我們的代碼保持簡單并避免任何不必要的導(dǎo)入。
我們應(yīng)該只在真正需要的時(shí)候使用defaultdict它,比如在對(duì)值進(jìn)行分組時(shí)。
錯(cuò)誤#5
我們總是忽略字典性能
我知道……字典很快。但是當(dāng)我們的字典變得太大時(shí),它的性能就會(huì)下降。
最好不要這樣寫:
my_dict = {i: i**2 for i in range(10_000_000)}
我們可以使用生成器表達(dá)式來節(jié)省內(nèi)存:
def squared_numbers():
for i in range(10_000_000):
yield i, i**2
my_dict = dict(squared_numbers())
它將降低我們的內(nèi)存使用量,并在我們真正需要時(shí)計(jì)算值。
錯(cuò)誤#6
我們使用setdefault()錯(cuò)誤的方式
你知道……初學(xué)者經(jīng)常犯這個(gè)錯(cuò)誤:
data = {}
if "name" not in data:
data["name"] = "kiran"
我知道……這可行。但我們有更好的方法:
data = {}
data.setdefault("name", "kiran")
這很清楚,我們不需要額外的if檢查。但是這段代碼有一個(gè)問題。
setdefault()總是會(huì)返回該值,即使它存在,正如我們?cè)谶@段代碼中看到的那樣:
name = data.setdefault("name", some_expensive_function())
"name"已經(jīng)存在,data但 Python 仍會(huì)調(diào)用。some_expensive_function()這會(huì)浪費(fèi)時(shí)間。
所以最好的方法是使用.get()
name = data.get("name", "kiran")
如果缺少鍵,此方法只會(huì)調(diào)用默認(rèn)值。非常簡單……
錯(cuò)誤 #7
有些人不使用Counter計(jì)數(shù)
通?!S多初學(xué)者會(huì)嘗試像這樣手動(dòng)計(jì)算物品:
words = ["apple", "banana", "apple"]
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
我知道……這行得通。但我想——我們可以做得更好。我們可以使用collections.Counter
from collections import Counter
word_count = Counter(words)
現(xiàn)在,我們的代碼更加清晰、更快。