Python - 从复杂对象的有序列表中删除重复项?

时间:2017-12-27 19:39:06

标签: python algorithm

我有以下形式从json制作的数百万字典的列表:

{
  "_id":XXX,
  "some_other":"fields",
  ...
}

列表需要按_id键进行安全排序,但是有重复_id的详细信息。与列表大小(最多约10-100)相比,真的很少重复。对于每个重复的_id,我只想采用第一个(或最后一个,对于它的确定性而言无关紧要)字典。在JavaScript中,我使用以下内容:

list.sort((a,b)=>a._id>b._id?1:(a._id<b._id?-1:0))
    .filter((ent,i,arr)=>i==0||ent!=arr[i-1])

但是我猜过滤器的python变种不允许访问项目的索引?在Python中有没有类似的简短方法来完成这样的事情?我找到了sorted(...)函数,它允许我按照我想要的方式对此列表进行排序,但是我仍然不知道如何过滤掉以下重复项(没有明显的,粗暴的循环)。

3 个答案:

答案 0 :(得分:2)

使用字典删除重复项(这将始终保留每个_id的最后一次出现):

d = {i['_id']: i for i in your_list}

然后按_id:

对其值进行排序
list(sorted(d.values(), key=lambda i: i['_id']))

答案 1 :(得分:2)

python中的惯用方法是:

sorted

注意,内置python itertools是一个稳定排序,使用名为timsort的自适应合并排序。

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D 是一个非常有用的模块,可以有效地实现各种惰性迭代器。 groupby是一个分组迭代器:

sorted

您可以使用python匿名函数和三元运算符(在Python中创建“条件表达式”)来创建javascript的音译。注意,Python的key=str.lower函数不使用比较器函数,它使用key-based function

  

key指定用于提取a的一个参数的函数   每个列表元素的比较键:None。默认   值为cmp(直接比较元素)。

在Python 2中,仍然可以使用与Javascript版本类似的cmp参数(例如,返回-1,1或0的函数)

key已被弃用,最后在Python 3中删除,转而使用SELECT * FROM table ORDER BY LEN(Field) ASC, Field ASC

答案 2 :(得分:1)

使用sortedfiltermap

d = [
    {
        "_id": 3,
        "some_other": "a"
    },
    {
      "_id": 1,
      "some_other": "b"
    },
    {
        "_id": 2,
        "some_other": "c"
    },
    {
        "_id": 2,
        "some_other": "d"
    }
]

sorted_d = sorted(d, key=lambda x: x['_id'])
map(
    lambda y: y[1],
    filter(
        lambda x: True if x[0]==0 else sorted_d[x[0]]["_id"] != sorted_d[x[0]-1]["_id"],
        enumerate(sorted_d)
    )
)

输出:

[{'_id': 1, 'some_other': 'b'},
 {'_id': 2, 'some_other': 'c'},
 {'_id': 3, 'some_other': 'a'}]