Зацикливание на вложенном словаре и удаление, если условие не выполняется (python) - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть список вложенных словарей:

[{'a': 1,
  'b': 'string',
  'c': [{'key1': 80,
         'key2': 'string',
         'key3': 4033},
        {'key1': 324,
         'key2': 'string',
         'key3': 4034,
         'key4': 1}]},
 {'a': 1,
  'b': 'string',
  'c': [{'key1': 80,
         'key2': 'string',
         'key3': 4033},
        {'key1': 324,
         'key2': 'string',
         'key3': 4034,
         'key4': 1,
         'key5': 2}]}]

Обратите внимание, что значения ключа c снова представляют собой список словарей.Теперь я хочу отфильтровать из этого списка все словари с ключом c, которые не содержат key1, key2, key3 & key4.

.сначала, второй и т. д. dict в списке, а затем зацикливание на вложенных dict с ключом c.Затем, если dict внутри c не соответствует моему требованию, я его удаляю.

Поэтому мой код будет:

for j in range(len(mydict)):
    for i in range(len(mydict[j]["c"])):
        if not all (k in mydict[j]["c"][i] for k in ("key1", "key2", "key3", "key4")):
            del(mydict[j]["c"][i])

Но я получаю IndexError: list index out of rangeошибка.Где моя ошибка?

Мой желаемый результат будет:

[{'a': 1,
  'b': 'string',
  'c': [{'key1': 324,
         'key2': 'string',
         'key3': 4034,
         'key4': 1}]},
 {'a': 1,
  'b': 'string',
  'c': [{'key1': 324,
         'key2': 'string',
         'key3': 4034,
         'key4': 1,
         'key5': 2}]}]

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Просто чтобы иметь другой вариант:

keep = {'key1', 'key2', 'key3', 'key4'}
for h in mydict:
    h['c'] = [ e for e in h['c'] if len(keep - set(e.keys())) == 0 ]
0 голосов
/ 20 февраля 2019

Если вам нужна другая перспектива:

def remove_keys(mydict):
    mydict2 = mydict
    keys = ['key1', 'key2', 'key3', 'key4']
    for xIndex, x in enumerate(mydict):
        for yIndex, y in enumerate(x['c']):
            if not all(key in y.keys() for key in keys):
                del mydict2[xIndex]['c'][yIndex]
    return mydict2

Возвращает новый словарь с изменениями.

0 голосов
/ 20 февраля 2019

Проблема в том, что с for i in range(len(mydict[j]["c"])): вы перебираете списки в dict, одновременно удаляя их из этих списков.Вместо этого вы можете заменить внутренний цикл списком:

for d in mydict:
    d['c'] = [d2 for d2 in d['c']
                 if all(k in d2 for k in ("key1", "key2", "key3", "key4"))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...