2016-04-30 70 views
2

這兩段代碼給出兩個不同的結果!爲什麼?設置字符串,循環之前和循環之後的不同行爲

len(sorted(set([w.lower() for w in text1]))) 
17231 

len(sorted([w.lower() for w in set(text1)])) 
19317 
+1

因爲你在做兩件完全不同的事情。 – thebjorn

+2

由於較低和較高形式的字符沒有相同的散列值,因此set函數並不假定它們是重複的,因此在將所有字符轉換爲小寫字母后,該集合可能會從字符串中刪除更多字符。 – Kasramvd

回答

0
>>> 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'} 
2

由於字符的下限和上限的形式不具有相同的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)) 
+1

沒有必要提及散列值。使用散列是實現的一個特性,即優化。如果hash('A')'和'hash('a')'相等,結果將是相同的,因爲最終該集檢查元素是否相等。 –

+0

@AlexHall不,我認爲這就是讓OP認爲結果應該是相同的,因爲顯然這兩個代碼是相同的(不改變任何特定的輸入) – Kasramvd

0

第一個版本將所有的字符串爲小寫,然後刪除重複,然後排序。第二個版本刪除重複,然後轉換爲小寫,然後排序。

因此,對於只有大小寫不同的每對輸入字符串,第二個版本將發出兩個匹配的(小寫)條目。

您是否看到其他區別?

編輯:您已將代碼更改爲僅包含結果列表的len(),因此您將看不到詳細信息。嘗試區分列表。