這兩段代碼給出兩個不同的結果!爲什麼?設置字符串,循環之前和循環之後的不同行爲
len(sorted(set([w.lower() for w in text1])))
17231
len(sorted([w.lower() for w in set(text1)]))
19317
這兩段代碼給出兩個不同的結果!爲什麼?設置字符串,循環之前和循環之後的不同行爲
len(sorted(set([w.lower() for w in text1])))
17231
len(sorted([w.lower() for w in set(text1)]))
19317
>>> text1 = 'Aa'
>>> set(text1) # has two elements because the input has two different elements
{'a', 'A'}
>>> [w.lower() for w in set(text1)]
['a', 'a']
>>> [w.lower() for w in text1]
['a', 'a']
>>> set([w.lower() for w in text1]) # has one element because the input has two equal elements
{'a'}
由於字符的下限和上限的形式不具有相同的hash value,設定的功能不承擔他們作爲重複。因此,在將所有字符轉換爲小寫字母后,set()
函數將在第一個代碼中刪除字符串中的更多字符。
請看下面的例子:
>>> text2 = 'ABCDEFabcdef'
>>>
>>> set(w.lower() for w in text2)
set(['a', 'c', 'b', 'e', 'd', 'f'])
>>> [w.lower() for w in set(text2)]
['a', 'a', 'c', 'b', 'e', 'd', 'f', 'f', 'c', 'b', 'e', 'd']
可以使用hash()
函數來查看字符的哈希值:
>>> hash('A')
8320025024
>>> hash('a')
12416037344
多一點:
現在,如果你想獲得字符較低的獨特結果,您應該使用第一種方法。但是,如果你正在處理一個大文本您更好地使用,而不是一個列表理解發電機表達:
set(w.lower() for w in text1))
沒有必要提及散列值。使用散列是實現的一個特性,即優化。如果hash('A')'和'hash('a')'相等,結果將是相同的,因爲最終該集檢查元素是否相等。 –
@AlexHall不,我認爲這就是讓OP認爲結果應該是相同的,因爲顯然這兩個代碼是相同的(不改變任何特定的輸入) – Kasramvd
第一個版本將所有的字符串爲小寫,然後刪除重複,然後排序。第二個版本刪除重複,然後轉換爲小寫,然後排序。
因此,對於只有大小寫不同的每對輸入字符串,第二個版本將發出兩個匹配的(小寫)條目。
您是否看到其他區別?
編輯:您已將代碼更改爲僅包含結果列表的len()
,因此您將看不到詳細信息。嘗試區分列表。
因爲你在做兩件完全不同的事情。 – thebjorn
由於較低和較高形式的字符沒有相同的散列值,因此set函數並不假定它們是重複的,因此在將所有字符轉換爲小寫字母后,該集合可能會從字符串中刪除更多字符。 – Kasramvd