根据键生成唯一字典列表

5 投票
10 回答
11961 浏览
提问于 2025-04-16 08:08

我有一个字典的列表:

     data = {}
     data['key'] = pointer_key
     data['timestamp'] = timestamp
     data['action'] = action
     data['type'] = type
     data['id'] = id

     list = [data1, data2, data3, ... ]

我该如何确保在这个列表中的每个数据项里,每个“键”只存在一个这样的元素呢?如果有两个相同的键,就按照时间戳来决定,时间戳最新的那个会被保留:

    list = [{'key':1,'timestamp':1234567890,'action':'like','type':'photo',id:245},
            {'key':2,'timestamp':2345678901,'action':'like','type':'photo',id:252},
            {'key':1,'timestamp':3456789012,'action':'like','type':'photo',id:212}]

    unique(list)

    list = [{'key':2,'timestamp':2345678901,'action':'like','type':'photo',id:252},
            {'key':1,'timestamp':3456789012,'action':'like','type':'photo',id:212}]

谢谢。

10 个回答

1

为了更清楚地说明,你有多个字典,但你想要确保每个字典中的数据['key']是唯一的?比如,如果data1['key'] = 'hello',你想确保data2['key'] = 'hello'是不被允许的?你希望这样做时只是抛出一个错误吗?这是一种验证的方法。(另外,最好不要把你的列表命名为'list',因为'list'在Python中是一个数据类型)

datalist = [datadict1, datadict2, datadict3]
big_key_list = []
for datadict in datalist:
    curkey = datadict.get('key')
    if curkey not in big_key_list:
        big_key_list.append(curkey)
    else:
        raise Exception("Key %s in two data dicts" % curkey)

现在,有一个更好的方法是创建一个新的类,继承自字典,这个类包含子字典,但不允许多个键有相同的值。这样在赋值时就会抛出错误,而不是你只能检查是否正常(如果不正常就不知道该怎么办,除了抛出错误)。

编辑:实际上,看看你可能想做的事情,你的数据设置得不太对。我这么说是因为你似乎想为每个条目创建一个单独的字典。这几乎肯定不是一个优雅的做法。

首先创建一个类:

class MyDataObject(object):
    def __init__(self, **kwargs):
        for k,v in kwargs:
            self.__dict__[k] = v

或者如果它们总是会有这四个固定参数:

class MyDataObject(object):
    def __init__(self, timestamp, action, obj_type, obj_id):
        self.timestamp = timestamp
        self.action = action
        self.type = obj_type
        self.id = obj_id

然后只需定义你的数据类型。

data = {}
data['key1'] = MyDataObject(timestamp='some timestamp', action='some action', type='some type', id = 1234)
data['key2'] = MyDataObject(timestamp='some timestamp2', action='some action2', type='some type2', id = 1235)

你可以这样访问你的数据:

data['key1'].timestamp # returns 'some timestamp'
data['key2'].action # returns 'some action2'

或者你甚至可以使用dict()来访问(例如,如果你有一个变量x='action',你想用它来访问数据,这样会很有帮助)。

data['key1'].__dict__('action') # returns 'some action'
data['key2'].__dict__('timestamp') # returns 'some timestamp2'

现在你就有了一个对象字典,其中键是唯一的,和键相关的数据被作为一个对象(类型为MyDataObject)保存。

5

我需要这个功能,但这里的回答我都不太满意。所以我做了一个简单又高效的版本。

def list_of_seq_unique_by_key(seq, key):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if x[key] not in seen and not seen_add(x[key])]

# Usage
# If you want most recent timestamp to win, just sort by timestamp first
list = sorted(list, key=lambda k: k['timestamp'], reverse=True)
# Remove everything with a duplicate value for key 'key'
list = list_of_seq_unique_by_key(list, 'key')
5

这是我的解决方案:

def uniq(list_dicts):
    return [dict(p) for p in set(tuple(i.items()) 
        for i in list_dicts)]

希望能对某些人有所帮助。

撰写回答