《Python Cookbook(第3版)中文版》——1.10 从序列中移除重复项且保持元素间顺序不变

简介:

本节书摘来自异步社区《Python Cookbook(第3版)中文版》一书中的第1章,第1.10节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.10 从序列中移除重复项且保持元素间顺序不变

1.10.1 问题

我们想去除序列中出现的重复元素,但仍然保持剩下的元素顺序不变。

1.10.2 解决方案

如果序列中的值是可哈希(hashable)的,那么这个问题可以通过使用集合和生成器轻松解决。示例如下[1]:

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]
>>>

只有当序列中的元素是可哈希的时候才能这么做。如果想在不可哈希的对象(比如列表)序列中去除重复项,需要对上述代码稍作修改:

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的作用是指定一个函数用来将序列中的元素转换为可哈希的类型,这么做的目的是为了检测重复项。它可以像这样工作:

>>> 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}]
>>>

如果希望在一个较复杂的数据结构中,只根据对象的某个字段或属性来去除重复项,那么后一种解决方案同样能完美工作。

1.10.3 讨论

如果想要做的只是去除重复项,那么通常足够简单的办法就是构建一个集合。例如:

>>> a
[1, 5, 2, 1, 9, 1, 5, 10]
>>> set(a)
{1, 2, 10, 5, 9}
>>>

但是这种方法不能保证元素间的顺序不变[2],因此得到的结果会被打乱。前面展示的解决方案可避免出现这个问题。

本节中对生成器的使用反映出一个事实,那就是我们可能会希望这个函数尽可能的通用——不必绑定在只能对列表进行处理。比如,如果想读一个文件,去除其中重复的文本行,可以只需这样处理:

with open(somefile,'r') as f:
    for line in dedupe(f):
        ...
相关文章
|
30天前
|
大数据 Python
使用Python查找字符串中包含的多个元素
本文介绍了Python中查找字符串子串的方法,从基础的`in`关键字到使用循环和条件判断处理多个子串,再到利用正则表达式`re模块`进行复杂模式匹配。文中通过实例展示了如何提取用户信息字符串中的用户名、邮箱和电话号码,并提出了优化策略,如预编译正则表达式和使用生成器处理大数据。
20 1
|
1月前
|
索引 Python
在Python中,如何快速地遍历列表中的每个元素?
在Python中,如何快速地遍历列表中的每个元素?
29 3
|
1月前
|
Python
利用Python处理列表中的重复元素的多种方法
利用Python处理列表中的重复元素的多种方法
46 0
|
1月前
|
Python
在Python中,如何使用列表推导式来遍历列表中的每个元素?
在Python中,如何使用列表推导式来遍历列表中的每个元素?
24 2
|
1月前
|
API Python
【python自动化】Playwright基础教程(四)事件操作①高亮&元素匹配器&鼠标悬停
【python自动化】Playwright基础教程(四)事件操作①高亮&元素匹配器&鼠标悬停
21 0
|
2月前
|
安全 Java 测试技术
Python 官方研讨会:彻底移除 GIL 真的可行么?
Python 官方研讨会:彻底移除 GIL 真的可行么?
40 0
|
3月前
|
Rust
Rust 编程小技巧摘选(8)
Rust 编程小技巧摘选(8)
65 0
Rust 编程小技巧摘选(8)
|
3月前
|
Python Java Go
Python每日一练(20230430) 移除元素、删除排序链表中的重复元素、搜索旋转排序数组II
Python每日一练(20230430) 移除元素、删除排序链表中的重复元素、搜索旋转排序数组II
46 0
Python每日一练(20230430) 移除元素、删除排序链表中的重复元素、搜索旋转排序数组II
|
3月前
|
算法 C++ Python
Python每日一练(20230425) 多数元素、二叉树层序遍历II、最接近的三数之和
Python每日一练(20230425) 多数元素、二叉树层序遍历II、最接近的三数之和
27 0
Python每日一练(20230425) 多数元素、二叉树层序遍历II、最接近的三数之和
|
3月前
|
Python Java Go
Python每日一练(20230418) 数组转BST、四数之和、排序数组首末元素
Python每日一练(20230418) 数组转BST、四数之和、排序数组首末元素
26 0
Python每日一练(20230418) 数组转BST、四数之和、排序数组首末元素

热门文章

最新文章