Я хочу найти наиболее оптимальный способ итерации значений в ключе в python.
У меня есть файл с этой структурой:
17 key1
18 key1
45 key2
78 key2
87 key2
900 key3
92 key4
поэтому мне нужно установить второй столбец как ключ (без повторения) и привязать к этому ключу все соответствующие ему значения (первый столбец).
'Ключ1': [ '17', '18']
'Ключ2': [ '45', '78', '87']
'Ключ3': [ '900']
'Key4': [ '92']
До сих пор я делаю это без использования словаря:
for line in file:
value, key = line.strip().split(None,1)
И затем я могу поместить его в словарь с
diction.setdefault(key, []).append(value)
поэтому после этого у меня есть хороший словарь, как мне было нужно.
Но после этого я должен перечитать файл для изменений. изменения могут возникать в ключах (парах) (добавлении/удалении) или только в значении (добавление/удаление). Как я могу проверить, произошло ли изменение ключей итераций по значениям?
UPD ***: для проверки ключей более или менее ясно:
if diction[key]:
но как итерировать значения внутри ключа? Мне нужно найти разницу, а затем добавить\удалить это значение \pair (если последнее значение ключа) из словаря?
Я предполагаю, что это можно сделать с помощью некоторого iteritem()\itervalues () или smthng, но я не знаком с этим.
Спасибо за помощь.
UPD ***
Спасибо @Joël. Наконец, я использовал 3 проверки. сначала добавляются все ключи:
set_old_dict = set(new_old.keys())
set_new_dict = set(new_dict.keys())
intersect = set_new_dict.intersection(set_old_dict)
def added(self):
return set_new_dict - intersect
def removed(self):
return set_old_dict - intersect
И тогда, если я не поймаю или уже обработал эти ситуации, я буду использовать вашу функцию:
def comp(old_dict, new_dict):
for key, old_val in old_dict.items():
new_val = new_dict[key]
print 'evolutions for', key
print 'new content:', [x for x in new_val if x not in old_val]
print 'removed content:', [x for x in old_val if x not in new_val]
Мой совет заключается в том, что если вам нужно перечитать входной файл, вы можете также заново создать свой словарь, но это зависит от времени, необходимого для создания словаря. По вашему запросу, возможно, быстрее проанализировать различия в файле и обновить словарь.
Вы можете взглянуть на модуль difflib
, а затем проанализировать различия. Исходя из этого, удаление может быть удалено в словаре, добавление добавляется по мере необходимости.
К сожалению, я готов поспорить, что вам будет сложно с выходом: это предназначено для чтения человеком, а не для машинного чтения, поэтому может быть лучший ответ.
EDIT, если вы хотите отслеживать изменения между версиями двух файлов, как написано в вашем комментарии, вы можете сравнить словари. Для ключей у вас уже есть то, что нужно.
Теперь для обновленных значений: если вы уверены, что ваши значения всегда будут списками строк, вы можете сделать то же самое, что и для сравнения ключей dict:
>>> def comp(old_dict, new_dict):
... for key, old_val in old_dict.items():
... new_val = new_dict[key] # warning: to be used on keys in both dict
... print 'evolutions for', key
... print 'new content:', [x for x in new_val if x not in old_val]
... print 'removed content:', [x for x in old_val if x not in new_val]
# now testing on a simple example
>>> o = {'key1': ['a', 'b', 'c']}
>>> n = {'key1': ['b', 'c', 'd']}
>>> comp(o, n)
evolutions for key1
new content: ['d']
removed content: ['a']
Предупреждение: эта функция работает только в том случае, если new_dict
содержит все ключи old_dict
, иначе создание new_val
не удастся. Вы можете легко обойти эту проблему, добавив сравнения клавиш в функции:
old_dict
, которые не находятся в new_dict
, удаляются.new_dict
а не в old_dict
являются дополнениями.Пожалуйста, опубликуйте свой результат в своем ответе, чтобы другие могли извлечь из этого выгоду.
if diction[key]:
используйтеif key in diction: