2015-02-24 3 views
0

У меня есть вложенный список (список списка), и я хочу удалить дубликаты, но я получаю сообщение об ошибке. Это пример:Получите уникальные значения из вложенного списка в python

images = [ 
    [ 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "marine-transportation-transports-maritimes.xml" 
     }, 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "railway-transportation-transports-ferroviaires.xml" 
     } 
    ], 
    [ 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "marine-transportation-transports-maritimes.xml" 
     }, 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "railway-transportation-transports-ferroviaires.xml" 
     } 
    ], 
    [ 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "marine-transportation-transports-maritimes.xml" 
     }, 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "railway-transportation-transports-ferroviaires.xml" 
     } 
    ] 
] 

Таким образом, в финале это images будет содержит только

[ 
    [ 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "marine-transportation-transports-maritimes.xml" 
     }, 
     { 
      "image_link": "1969.1523.001.aa.cs.jpg", 
      "catalogue_number": "1969.1523", 
      "dataset_name": "railway-transportation-transports-ferroviaires.xml" 
     } 
    ] 
] 

Я использую set функцию

set.__doc__ 
'set() -> new empty set object\nset(iterable) -> new set object\n\nBuild an unor 
dered collection of unique elements.' 

мой журнал трассировки:

list(set(images)) 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
TypeError: unhashable type: 'list' 

Для того, чтобы сделать его проще, как я могу удалить все дубликаты в этом примере

example = [ [{'a':1, 'b':2}, 'w', 2], [{'a':1, 'b':2}, 'w', 2] ] 
#result 
#example = [[{'a':1, 'b':2}, 'w', 2] ] 
+0

unhashable типа: «список» Это означает, что он не может иметь хеш-список, потому что список изменен, вы не можете хешировать изменяемый объект, если ваши данные статичны, вы можете изменить список для кортежей. – danielfranca

+0

Проблема с dicts заключается в том, что даже если вы вставляете их в кортежи (неизменяемые), у вас нет никаких средств для определения порядка элементов, что нарушит сравнение. Хорошее решение предполагает перевод этой структуры данных в неизменяемую структуру хешируемых данных, а затем очистку дубликатов (например, с помощью 'set'). – Lachezar

ответ

1

The setdict и контейнеры опираются на хеширования данных. Другие изменчивые контейнеры, такие как list (и сами и dict), не могут быть хэшированы. Они могут быть изменены позже (изменяемые), поэтому постоянное значение хэша не имеет смысла.

Но вы можете преобразовать все свои данные в (вложенные) кортежи и, наконец, в set. Поскольку tuple является неизменяемым контейнером - и ваши данные хешируются (строки) - он может работать. Вот противный один вкладыш для специальных изображений случай, который делает трюк:

images_Set = set([tuple([tuple(sorted(image_dict.items())) 
    for image_dict in inner_list]) for inner_list in images]) 

и

print(images_set) 

отпечатки

{((('catalogue_number', '1969.1523'), 
    ('dataset_name', 'marine-transportation-transports-maritimes.xml'), 
    ('image_link', '1969.1523.001.aa.cs.jpg')), 
    (('catalogue_number', '1969.1523'), 
    ('dataset_name', 'railway-transportation-transports-ferroviaires.xml'), 
    ('image_link', '1969.1523.001.aa.cs.jpg')))} 

EDIT: Там в не гарантируется заказ для словаря items. Следовательно, я также добавил sorted, чтобы обеспечить заказ.

+0

Как насчет порядка элементов при переводе dicts в tupples? '' Подробности реализации CPython: ключи и значения перечислены в произвольном порядке, который является неслучайным, варьируется в разных реализациях Python и зависит от истории вставки и удаления словаря. '' '(Https: //docs.python .org/2/library/stdtypes.html # dict.items) – Lachezar

+0

Вы правы, я добавил сортировку к нему – SmCaterpillar

+0

спасибо @SmCaterpillar за ваше объяснение. Благодаря Kasra, Avinash, Lucho y'all есть отличный ответ. –

1

Похоже, вы хотите что-то вроде этого,

>>> example = [ [{'a':1, 'b':2}, 'w', 2], [{'a':1, 'b':2}, 'w', 2] ] 
>>> l = [] 
>>> for i in example: 
     if i not in l: 
      l.append(i) 


>>> l 
[[{'b': 2, 'a': 1}, 'w', 2]] 
+0

спасибо @Avinash! Я думаю, для этого нет встроенных функций! –

1

Вы можете использовать compiler.ast.flatten выравниваться свой список, а затем конвертировать словарь в hashable объекта копаться множества затем преобразовать обратно в Словаре, только с одним списком понимания:

>>> from compiler.ast import flatten 
>>> [dict(item) for item in set(tuple(i.items()) for i in flatten(images))] 
[{'image_link': '1969.1523.001.aa.cs.jpg', 'catalogue_number': '1969.1523', 'dataset_name': 'marine-transportation-transports-maritimes.xml'}, {'image_link': '1969.1523.001.aa.cs.jpg', 'catalogue_number': '1969.1523', 'dataset_name': 'railway-transportation-transports-ferroviaires.xml'}] 
Смежные вопросы