2010-11-05 2 views
3

Рассмотрите этот формат словаря.Удалите повторяющиеся записи из вложенного словаря, если два значения совпадают, в Python

{1:{'name':'chrome', 'author':'google', 'url':'http://www.google.com/' }, 
2:{'name':'firefox','author':'mozilla','url':'http://www.mozilla.com/'}} 

Я хочу удалить все предметы с тем же именем и автором.

Я могу легко удалить повторяющиеся записи на основе ключей, поместив все ключи в набор и, возможно, расширив его, чтобы работать с определенным значением, но это похоже на дорогостоящую операцию, которая повторяется через словарь несколько раз. Я бы не знал, как это сделать с двумя значениями эффективным образом. Это словарь с тысячами предметов.

+1

Как вы получаете эти данные? Вы могли бы создать его с помощью сопоставления словаря (имя, автор) в URL-адресе в первую очередь, тогда therfe не нужно было бы вообще этого делать. –

+1

Может быть, просто измените структуру dict и задайте имя, а автор - ключ к dict? – demas

+0

Я специально не упоминал об этом, но также хочу подсчитать удаленные элементы для внутренней ссылки, выполнив 'len (dict)' до и после. И изменение структуры не имеет значения, потому что я удаляю дубликаты ключей. Я немного упростил словарь в этом примере. – 2010-11-05 10:55:00

ответ

3

Перебор по словарю, отслеживанием встречающихся (name, author) кортежей, как вы идете и удалить те, которые вы уже сталкивались:

def remove_duplicates(d): 
    encountered_entries = set() 
    for key, entry in d.items(): 
     if (entry['name'], entry['author']) in encountered_entries: 
      del d[key] 
     else: 
      encountered_entries.add((entry['name'], entry['author'])) 
+1

Невозможно изменить dict во время итерации над 'd.keys()' - это дает неопределенные результаты. –

+1

@Sven: Итерация над 'd.keys()' и изменение dict в Python 2.5 (о котором идет речь). 'd.keys()' возвращает список ключей в dict, и на этот список не влияет последующая модификация dict. Модифицирование dict при итерации по самому dict, или над 'd.iterkeys()', 'd.itervalues ​​()' или 'd.iteritems()' не совсем нормально. –

+0

@ Pär: Вы правы :) Я всегда использую 'iterkeys()', чтобы избежать промежуточного списка. –

1

Давайте посмотрим, если это работает ...

from itertools import groupby 

def entry_key(entry): 
    key, value = entry 
    return (value['name'], value['author']) 

def nub(d): 
    items = d.items() 
    items.sort(key=entry_key) 
    grouped = groupby(items, entry_key) 
    return dict([grouper.next() for (key, grouper) in grouped]) 
+0

Я пробовал это, но у Python 2.5 нет 'next()'. Возможно, мне следовало бы поместить это в текст, а не только тег. – 2010-11-05 11:09:48

+0

О, ладно. Просто используйте .next(). – sykora

+0

Спасибо, это работает. Однако я профилировал его, а другой ответ примерно в два раза быстрее. – 2010-11-05 11:34:32

 Смежные вопросы

  • Нет связанных вопросов^_^