問題:怎樣在Python的一個序列上面保持元素順序的同時消除重復的值?
answer:如果序列上的值都是hashable 類型,那么可以很簡單的利用集合或者生成器來解決這個問題。
eg1:
def dedupe(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)
下面是使用上述函數的例子:
>>> a = [1, 5, 2, 1, 9, 1, 5, 10]
>>> list(dedupe(a))
[1, 5, 2, 9, 10]
eg2:
這個方法僅僅在序列中元素為hashable 的時候才管用。
如果你想消除元素不可哈希(比如dict 類型) 的序列中重復元素的話,你需要將上述代碼稍微改變一下,就像這樣:
def dedupe(items, key=None):
seen = set()
for item in items:
val = item if key is None else key(item)
if val not in seen:
yield item
seen.add(val)
這里的key 參數指定了一個函數,將序列元素轉換成hashable 類型。下面是它的
用法示例:
>>> a = [ {'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
>>> list(dedupe(a, key=lambda d: (d['x'],d['y'])))
[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
>>> list(dedupe(a, key=lambda d: d['x']))
[{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
如果你想基於單個字段、屬性或者某個更大的數據結構來消除重復元素,第二種方案同樣可以勝任。
附:
hash是什么意思?
Hash,一般翻譯成‘散列’,也有直譯成‘哈希’的,把任意長度的輸入通過散列算法,變成固定長度的輸出。該輸出就是散列值。
這種轉換是一種壓縮映射,散列值的空間通常遠小於輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。
簡單的說是將一種任意長度的消息壓縮到某一固定長度的消息摘要的函數。
HASH主要用於信息安全領域中加密算法,他把一些不同長度的信息轉化成雜亂的128位編碼里,叫做HASH值。
也就是說hash就是找到一種數據內容和數據存放地址之間的映射關系
著名的hash算法,MD5和SHA1是目前應用最廣泛的Hash算法,他們都是以MD4為基礎設計的