官术网_书友最值得收藏!

3.1.3 序列去重并保持順序

從序列中刪除元素或刪除重復元素是非常頻繁的操作,若需要在刪除的同時保持序列中元素的順序,怎樣操作可以更優雅且高效地完成刪除?

如果序列上的值都是hashable類型,那么可以簡單地利用集合或者生成器來解決這個問題,代碼(sequence_delete_exp.py)示例如下:


def dedupe_1(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)


sequence_v = [1, 2, 3, 5, 2, 3]
print(list(dedupe_1(sequence_v)))

執行py文件,輸出結果如下:


[1, 2, 3, 5]

當序列中元素為hashable類型時,上述處理方法沒有問題;當序列中元素不是hashable類型時(比如dict類型),這種寫法就做不到去重。

如果元素不可哈希,要消除序列中重復元素,需要將上述代碼稍做改變,代碼(sequence_delete_exp.py)示例如下:


def dedupe_2(items, key=None):
    seen = set()
    for item in items:
        # val = item if key is None else key(item)
        if (val := item if key is None else key(item)) not in seen:
            yield item
            seen.add(val)

sequence_v = [{'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
print(list(dedupe_2(sequence_v, key=lambda d: (d['x'],d['y']))))
print(list(dedupe_2(sequence_v, key=lambda d: d['x'])))

執行py文件,輸出結果如下:


[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
[{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]

示例代碼中使用了Python3.8的新特性——賦值表達式(:=),在后續的很多地方會用到該表達式。

代碼中的key參數指定了一個函數,用于將序列元素轉換成hashable類型。

如果想基于單個字段、屬性或者某個更大的數據結構來消除重復元素,該方案同樣可以勝任。如果只是想消除重復元素,簡單地構造一個set集合即可實現。使用set集合不能維護元素的順序,生成的結果中的元素位置會被打亂。

上面示例中使用了生成器函數,使得定義的函數更加通用。

主站蜘蛛池模板: 台北市| 永兴县| 宁都县| 张家港市| 湘潭市| 江口县| 察隅县| 屏山县| 和田市| 华亭县| 固原市| 玉山县| 金门县| 如东县| 临清市| 舟山市| 土默特右旗| 东乡县| 林口县| 喀什市| 蓬安县| 永安市| 新邵县| 桑日县| 佳木斯市| 陆川县| 页游| 乐昌市| 当涂县| 遵义县| 乐平市| 隆安县| 天祝| 桃源县| 改则县| 交口县| 竹溪县| 朝阳区| 鄄城县| 岳阳市| 都江堰市|