Страницы

Поиск по вопросам

среда, 18 декабря 2019 г.

Как удалить из списка словари с повторяющимся полем?

#python


У меня есть список словарей вроде такого:

[
    {'id': 1, 'name': 'one'},
    {'id': 2, 'name': 'two'},
    {'id': 1, 'name': 'one'},
    {'id': 3, 'name': 'three'}
]


Я хочу, чтобы остался список с уникальными id (неважно, что в остальных полях словаря).
То есть, из примера выше должно получиться это:

[
    {'id': 1, 'name': 'one'},
    {'id': 2, 'name': 'two'},
    {'id': 3, 'name': 'three'}
]

    


Ответы

Ответ 1



Чтобы оставить в списке только словари с уникальным id (убрать повторения): result = list({d['id']: d for d in list_of_dicts}.values()) Это линейный по времени и по памяти алгоритм. Результат: [{'id': 1, 'name': 'one'}, {'id': 2, 'name': 'two'}, {'id': 3, 'name': 'three'}]

Ответ 2



from itertools import groupby lst = [ {'id': 1, 'name': 'one'}, {'id': 2, 'name': 'two'}, {'id': 1, 'name': 'one'}, {'id': 3, 'name': 'three'} ] key = lambda dct: dct['id'] lst.sort(key=key) lst = [list(tpl[1])[0] for tpl in groupby(lst, key=key)] print(lst)

Ответ 3



Я бы, наверное, использовал словарь. lst = [ {'id': 1, 'name': 'one'}, {'id': 2, 'name': 'two'}, {'id': 1, 'name': 'one'}, {'id': 3, 'name': 'three'} ] d = {} for a in lst: d[a['id']] = a d.items()

Ответ 4



lst = [{'id': 1, 'name': 'one'}, {'id': 2, 'name': 'two'}, {'id': 1, 'name': 'one'}, {'id': 3, 'name': 'three'}] items = lambda d: tuple(d.items()) list(map(dict, set(map(items, lst)))) сравнение быстродействия способов: from timeit import Timer from itertools import groupby def test_1(items=lambda d: tuple(d.items())): list(map(dict, set(map(items, lst)))) def test_2(): d = {} for a in lst: d[a['id']] = a list(d.values()) def test_3(key=lambda dct: dct['id']): lst.sort(key=key) [next(dups) for _, dups in groupby(lst, key=key)] def test_4(): list({d['id']: d for d in lst}.values()) def test_5(): result = [] _id = [] rapp = result.append iapp = _id.append for d in lst: i = d['id'] if i not in _id: iapp(i) rapp(d) if __name__ == '__main__': gbls = globals() for fn in sorted(k for k in gbls if k.startswith('test_')): print('{:<6} = {:.2} сек'.format(fn, Timer(gbls[fn]).timeit())) out: test_1 = 9.4 сек test_2 = 1.8 сек test_3 = 5.8 сек test_4 = 1.9 сек test_5 = 1.9 сек

Комментариев нет:

Отправить комментарий