Удаление нескольких элементов в диктофоне

Я искал ошибку, которую он мне дает, но я не очень хорошо это понимаю. Они что-то сделали с for k, v in dbdata.items, но у меня это тоже не сработало, выдает другие ошибки.

Ну, я хочу, чтобы удалить несколько элементов.

tskinspath = ['1', '2']   

#
dbdata = {}
dbdata['test'] = {}
dbdata['test']['skins_t'] = {}

# Adds the items
dbdata['test']['skins_t']['1'] = 1
dbdata['test']['skins_t']['2'] = 0
dbdata['test']['skins_t']['3'] = 0
dbdata['test']['skins_t']['4'] = 0

# This doesn't work
for item in dbdata["test"]["skins_t"]:

     if item not in tskinspath:

        if dbdata["test"]["skins_t"][item] == 0:

                    del dbdata["test"]["skins_t"][item]

# exceptions.RunetimeError: dictonary changed size during iteration

person Community    schedule 07.10.2013    source источник


Ответы (3)


Вместо того, чтобы перебирать словарь, перебирайте dict.items():

for key, value in dbdata["test"]["skins_t"].items():
     if key not in tskinspath:
        if value == 0:
            del dbdata["test"]["skins_t"][key]

В py3.x используйте list(dbdata["test"]["skins_t"].items()).

Альтернатива:

to_be_deleted = []
for key, value in dbdata["test"]["skins_t"].iteritems():
     if key not in tskinspath:
        if value == 0:
            to_be_deleted.append(key)
for k in to_be_deleted: 
    del dbdata["test"]["skins_t"][k]
person Ashwini Chaudhary    schedule 07.10.2013
comment
Так это быстрее, чем первый ответ, если данных много или лучше? Просто хочу убедиться, что я использую наиболее точный ответ. - person ; 07.10.2013
comment
Это работает в Python2 (где items() возвращает список), но не в Python3 (где items() возвращает представление базового словаря). Я не знаю, какова политика SO в отношении того, какую версию Python следует предполагать, когда спрашивающий не говорит. - person Steve Jessop; 07.10.2013
comment
@Frederik items() вернет список a пар ключ-значение, а set(set(dbdata['test']['skins_t'])) вернет set ключей. Таким образом, с точки зрения набора памяти будет более эффективно. - person Ashwini Chaudhary; 07.10.2013
comment
@Frederik Я добавил еще одно решение, для этого потребуется меньше памяти. - person Ashwini Chaudhary; 07.10.2013

В сообщении об ошибке говорится: вам не следует изменять словарь, который вы повторяете. Пытаться

for item in set(dbdata['test']['skins_t']):
   ...

Таким образом, вы перебираете набор, содержащий все ключи из dbdata['test']['skins_t'].

person Lev Levitsky    schedule 07.10.2013
comment
Почему он говорит мне, что это из соображений безопасности? + P.S Это вопрос из коробки. Я просто хочу убедиться, что я использую это правильно. Нет никакой разницы между if item not in tskinspath: if not item in tskinspath: Что использовать? - person ; 07.10.2013
comment
@Frederik not in более удобочитаем и однозначен с точки зрения приоритета. Его следует использовать. - person Lev Levitsky; 07.10.2013
comment
@Frederik stackoverflow.com/questions/17659303/ - person Ashwini Chaudhary; 07.10.2013

Поскольку детали вопроса находятся в стороне от вопроса, если вы ищете решение, которое удаляет несколько ключей из данного dict, используйте этот фрагмент

[s.pop(k) for k in list(s.keys()) if k not in keep]

Кроме того, вы можете создать новый dict через понимание.

new_dict = { k: old_dict[k] for k in keep }
person nehem    schedule 10.10.2017