Как удалить все элементы определенного ключа в списке диктов? - PullRequest
0 голосов
/ 29 июня 2009

Я пытаюсь удалить некоторые элементы диктов на основе их ключа, вот мой код:

d1 = {'a': 1, 'b': 2}
d2 = {'a': 1}

l = [d1, d2, d1, d2, d1, d2]

for i in range(len(l)):
    if l[i].has_key('b'):
        del l[i]['b']

print l

Вывод будет:

[{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}]

Есть ли лучший способ сделать это?

Ответы [ 4 ]

16 голосов
/ 29 июня 2009
d1 = {'a': 1, 'b': 2}
d2 = {'a': 1}
l = [d1, d2, d1, d2, d1, d2]
for d in l:
    d.pop('b',None)
print l
3 голосов
/ 29 июня 2009

Небольшое упрощение:

   for d in l:
      if d.has_key('b'):
         del d['b']

Некоторые люди могут также сделать

   for d in l:
      try:
         del d['b']
      except KeyError:
         pass

Перехват таких исключений не считается дорогим в Python, как в других языках.

2 голосов
/ 29 июня 2009

Мне нравится ваш способ сделать это (за исключением того, что вы используете переменную цикла, но другие уже указали на это), это явный и простой для понимания Если вы хотите что-то, что минимизирует набор текста, то это работает:

[x.pop ('b', None) для x в l]

Обратите внимание, что будет удален только один «b», потому что ваш список содержит ссылки на словари. Запустите приведенный выше код, а затем распечатайте d1, и вы заметите, что фактически вы также удалили клавишу b из d1.

Чтобы избежать этого, вам необходимо скопировать словари:

d1 = {'a': 1, 'b': 2}
d2 = {'a': 1}

l = [d1.copy(), d2.copy(), d1.copy(), d2.copy(), d1.copy(), d2.copy()]
[b.pop('b', None) for b in l]

d1 теперь сохранит клавишу b.

0 голосов
/ 29 июня 2009

d1 = {'a': 1, 'b': 2} d2 = {'a': 1}

l = [d1, d2, d1, d2, d1, d2]

для i в диапазоне (len (l)): если l [i] .has_key ('b'): del l [i] ['b']

печать л

Вот небольшой обзор вашего кода:

  1. итерации по списку выполняются не так, как в C. Если вам не нужна ссылка на индекс списка, лучше использовать для элемента в l, а затем заменить l [i] на item.
  2. для проверки существования ключа вы можете просто написать, если 'b' в l [i]

Итак, ваш код становится:

for item in l:
    if 'b' in item:
        del item['b']

Еще одна вещь, с которой вам нужно быть осторожным, это то, что на первой итерации, которая вызывает del, вы фактически удалите все, что вам нужно, поскольку d1 является изменяемым. Вы должны думать, что d1 является ссылкой, а не значением (немного похоже на указатель в C).

Как сказал Леннарт Регебро, чтобы оптимизировать ваш код, вы также можете использовать списочное понимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...