在練習List Comprehension Debug的時候遇到一件事很困惑
目的是要取List裡面各項的第一個字母
country_list=['Aasdf', 'Abasdf', 'Basdf', 'Casdr', 'Dasdf','Elkj']
keys = []
#一般用for loop產生的迴圈
for i in country_list:
if i[0] not in keys:
keys.append(i[0])
print(keys)
# ['A', 'B', 'C', 'D', 'E']
keys = [(i[0]) for i in country_list if i[0] not in keys]
print(keys)
# ['A', 'A', 'B', 'C', 'D', 'E']
兩種結果卻不同一直想不透?
請教網上各位 str[index] 與 list.append(str[index]) 究竟有甚麼差別~
[From GPT]
你遇到的這個問題其實是由於 List Comprehension 中的條件判斷是在創建列表時進行的,導致結果與預期不符。
讓我們來看看這兩個例子:
在這個例子中,keys
列表是逐步構建的。每當新的元素被加入 keys
之後,這個列表就會立即更新。因此,當 if i[0] not in keys
條件被評估時,它是基於當前的 keys
列表。
keys = []
for i in country_list:
if i[0] not in keys:
keys.append(i[0])
而在 List Comprehension 的例子中,當條件 if i[0] not in keys
被評估時,它是基於原始的、未被修改的 keys
列表。也就是說,在整個 List Comprehension 執行過程中,keys
列表不會被更新或改變。這就是為什麼你的 List Comprehension 代碼會重複加入 'A':因為在處理第二個元素 'Abasdf' 時,keys
仍然是空的。
keys = [(i[0]) for i in country_list if i[0] not in keys]
在這個例子中,keys
列表只會在 List Comprehension 執行完畢後才會被賦予新的值,這就導致了你觀察到的不同行為。
如果你想使用 List Comprehension 並且避免重複,你可以考慮使用集合(Set)來進行快速的成員資格檢查,並在最後轉換回列表,如下所示:
keys = list({i[0] for i in country_list})
這段代碼首先創建一個集合(Set)來保留所有唯一的首字母,然後將這個集合轉換為列表。這樣可以保證每個字母只會出現一次。
你的 list comprehension 寫法實際上等於以下這樣:
>>> keys = []
>>> _keys = [] # list comprehension 建立的新串列
>>> for i in country_list:
... if not i[0] in keys: # 這裡 keys 都是指向原本的空串列
... _keys.append(i[0]) # 將首字母加到新建立的串列中
... keys = _keys # 迴圈結束後才會將新串列指派給 keys
>>> keys
['A', 'A', 'B', 'C', 'D', 'E']
所以在比對首字母是否出現在 keys 中時, 這個 keys 都是指向原本的空串列, 導致每一個字串的首字母都會加入到新建立的 _keys 串列中。
List comprehensions are useful and can help you write elegant code that's easy to read and debug, but they're not the right choice for all circumstances. They might make your code run more slowly or use more memory.https://mexicoonlinepharmacy.org/