维护序列项顺序的同时消除重复项

在序列中,经常会碰到有重复项的情况,有时需要消除重复的项。

解决方案:使用set来构造无重复数据项类型。如:

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

使用set构造数据后,原始的序列元素失去了当初的相对顺序。同时简单的使用set会有另一个问题:可哈希。我们知道,像list中包含list或dict等符合类型且作为set的构造函数参数进行set对象创建时,会有以下报错:

>>> c = [{'x': 1, 'y': 2}, {'x': 2, 'y': 3}]
>>> set(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

为了解决上述问题,我们可以写一个函数先消除hash的序列的重复项消除,同时保持原有的子项的相对顺序。

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]

通过构造一个生成器,并按原始顺序遍历items。每次遍历的时候,检查元素是否在集合容纳器中,若不在,则返回,并添加到set中。若已在set中,则跳过,继续遍历。

该函数仅对序列中所有子项全部可hash时有用。负责在进行集合add时会报错。

我们可以改进上述函数的实现,使其可以对不可hash(如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)

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

提供一个类似max, min中的key函数参数,然后在实际调用时使用lambda匿名函数,实际val的值由匿名函数的返回值提供,若key不为None时。
>>>

原文地址:https://www.cnblogs.com/jeffrey-yang/p/11290841.html

时间: 2024-10-04 21:59:34

维护序列项顺序的同时消除重复项的相关文章

C#中去除List&lt;T&gt;中重复项的问题/LINQ Distinct重复项

List<T>是.NET中最常用的一种数据结构了,我们常常把需要操作的对象都放到一个List<T>里面.有的时候,我们需要让List<T>中的数据保持唯一性,也就是说List中的数据不能有重复的项.我们知道,List<T>中可以存放任意的类型,如List<int>,List<string>等.为了剔除List<T>中的重复项,.NET为我们提供了一个Distinct()函数.对于普通类型的List,我们可以直接调用该函数剔

Excel2003 去除重复项

利用 数据透视表 间接 获得 非重复项 1] 选中要去除重复项 的列 数据 2] 3]将选中列移动到 左侧 即可 4]

【python cookbook】【数据结构与算法】10.从序列中移除重复项且保持元素间顺序不变

问题:从序列中移除重复的元素,但仍然保持剩下的元素顺序不变 解决方案: 1.如果序列中的值时可哈希(hashable)的,可以通过使用集合和生成器解决. 2.如果序列时不可哈希的,想要去除重复项,需要对上述代码稍作修改: key参数的作用是指定一个函数用来将序列中的元素转化为可哈希的类型,如此可以检测重复项.

JAVA中消除list中重复项

/**      * 消除list中重复项      * @param srcList      * @return      */     public static List<GpsData> dealRepeat(List<GpsData> srcList){         for(int m =0; m<srcList.size(); m++){              String lat1=srcList.get(m).getLat();           

多表合并且去掉重复项

数据库问题:多个表中合并去掉重复项 两个表合并起来,去掉某行相同的项,正好把多表查询系统复习一下: 多表查询 (也叫连接查询,此处为基于两个表的连接查询)如果一个查询需要对多个表进行操作就称为连接查询,连接查询的结果集或结果称为表之间的连接.连接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征.select 表1.字段名1,表2.字段名2,...from 表1,表2where 连接条件SQL-92标准所定义的FROM子句的连接语法格式为:FROM 表名 joi

网易2017春招笔试真题编程题集合——消除重复元素

时间限制:1秒 空间限制:32768K 小易有一个长度为n序列,小易想移除掉里面的重复元素,但是小易想是对于每种元素保留最后出现的那个.小易遇到了困难,希望你来帮助他. 输入描述: 输入包括两行: 第一行为序列长度n(1 ≤ n ≤ 50) 第二行为n个数sequence[i](1 ≤ sequence[i] ≤ 1000),以空格分隔 输出描述: 输出消除重复元素之后的序列,以空格分隔,行末无空格 输入例子: 9 100 100 100 99 99 99 100 100 100 输出例子: 9

笔试算法题(28):删除乱序链表中的重复项 &amp; 找出已经排好序的两个数组中的相同项

出题:给定一个乱序链表,节点值为ASCII字符,但是其中有重复项,要求去除重复项并保证不改变剩余项的原有顺序: 分析:创建一个256(2^8)大小的bool数组,初始化为false,顺序读取链表,将字母对应位置为false的重新标记为true并保留节点,将字母对 应位置为true的保持并删除节点:时间复杂度为O(N),空间复杂度为常量.注意删除节点和不删除节点的情况下,pre和cur的移动操作不相同: 解题: 1 struct Node { 2 char value; 3 Node* next;

1798: [Ahoi2009]Seq 维护序列seq

1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5886  Solved: 2087[Submit][Status][Discuss] Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和

二维数组去除特定键的重复项

<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action { //原始数据 /*Array ( [0] => Array ( [ap] => 23 [ac] => 569418 ) [1] => Array ( [ap] => 23 [ac] => 569520 ) [2] => Array ( [ap] => 23 [ac] => 569533 ) )*/ //除去重复值后的数据 /*