#python-3.x #dictionary
#python-3.x #словарь
Вопрос:
Есть ли способ обновить словарь во время итерации, чтобы избежать RuntimeError: dictionary changed size during iteration
?
То, что я пытаюсь сделать, это вставить некоторые ключи во внутренние словари, если условие выполнено. Для интенции дан следующий словарь:
D = {'a': {'s': 1,'b': 2}, 's': {'a': -1, 'c': 3}, 'b': {'z': 2, 'x': 4, 'a': -2}}
То, что я пытаюсь получить, это:
D = {'a': {'s': 1,'b': 2}, 's': {'c': 3}, 'b': {'z': 2, 'x': 4}}
Обратите внимание, что 's'
'b'
'a'
во внутренних словарях отсутствует ключ in и dictionary values, потому что a
в D уже есть ключ value, который имеет 's'
'b'
значения и as .
Что я пробовал до сих пор:
for k, v in D.items():
for i, j in v.items():
if i in D and k in D[i]:
D.pop(i)
Условие должно проверять, есть ли во внутреннем словаре, скажем 's'
, во внутреннем словаре, 'key'
который на самом деле является 'key'
D
словарем of . Здесь не рассматривается порядок. Таким образом, во 's'
внутреннем словаре 'a'
должно быть удалено, потому что есть D['a']
, который на самом деле имеет 's'
во внутреннем словаре. Та же логика справедлива для 'b'
внутреннего словаря, поскольку есть 'a'
key
in inner 'b'
и D['a']
has 'b'
, я бы удалил 'a'
из D['b']
и просто сохранил D['a']['b']
Но это привело бы меня к появлению предметов, которые я хочу сохранить. Поскольку я планирую работать с большим словарем словарей, что было бы лучшим вариантом здесь?
Комментарии:
1. Пожалуйста, уточните, какое условие вы хотите проверить. Я имею в виду, ваше
if
утверждение выглядит странно.2. Почему ваш желаемый результат есть
{'a': {'s': 1,'b': 2}
, но вы также говоритеSo in 's' inner dictionary 'a' should be removed
?
Ответ №1:
Если я правильно понимаю, вы хотите удалить каждую запись во внутренних словарях D, для которых ключ уже был определен в D. Обратите внимание, что здесь вы рассматриваете словарь как упорядоченную последовательность, хотя словарь Python по своей сути неупорядочен.
Вместо того, чтобы пытаться изменять существующий словарь во время итерации по нему, создайте новый словарь и добавляйте к нему значения в for
цикле.
Рабочая реализация:
D = {'a': {'s': 1,'b': 2}, 's': {'a': -1, 'c': 3}, 'b': {'z': 2, 'x': 4, 'a': -2}}
newdict = {}
for k_outer,v_outer in D.items():
newdict[k_outer] = {}
for k_inner,v_inner in v_outer.items():
if k_inner not in newdict.keys():
newdict[k_outer][k_inner] = v_inner
print(newdict)
D = newdict
Вывод:
{'a': {'s': 1, 'b': 2}, 's': {'c': 3}, 'b': {'z': 2, 'x': 4}}
Или, если вы абсолютно хотите изменить D «на лету», тогда используйте .copy()
which позволяет вам перебирать копию исходного словаря при изменении исходного словаря внутри цикла:
D = {'a': {'s': 1,'b': 2}, 's': {'a': -1, 'c': 3}, 'b': {'z': 2, 'x': 4, 'a': -2}}
seen = []
for k_outer,v_outer in D.copy().items():
seen.append(k_outer)
for k_inner,v_inner in v_outer.copy().items():
if k_inner in seen:
D[k_outer].pop(k_inner)
print(D)
Вывод:
{'a': {'s': 1, 'b': 2}, 's': {'c': 3}, 'b': {'z': 2, 'x': 4}}