2013-10-07 7 views
0

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

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

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 

ответ

0

Вместо Перебор словаря, перебрать 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] 
+0

Так что это быстрее, чем первый ответ, если есть много данных или лучше? Просто хочу убедиться, что я использую самый точный ответ. –

+0

Это работает в Python2 (где 'items()' возвращает список), но не в Python3 (где 'items()' возвращает представление базового словаря). Я не знаю, что такое политика SO, на какую версию Python следует предполагать, когда вопросник не говорит. –

+0

@Frederik 'items()' будет возвращать список a из пары ключей, значений и 'set (set (dbdata ['test'] ['skins_t']))' будет возвращать 'set' ключей. Так, в условия набора памяти будут более эффективными. –

0

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

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

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

+0

Почему это говорит мне, что это из-за соображений безопасности? + P.S Это вопрос из коробки. Я просто хочу, чтобы убедиться, что я тоже воспользуюсь этим. Нет никакого различия между 'if item not in tskinspath:' 'if not item в tskinspath:' Что использовать? –

+0

@Frederik 'not in' является более удобочитаемым и однозначным с точки зрения приоритета. Его следует использовать. –

+0

@Frederik http://stackoverflow.com/questions/17659303/what-is-more-pythonic-for-not –

0

В деталях вопроса является в стороне от вопроса, если вы ищете решение, которое удаляет несколько ключей от данного 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 } 
Смежные вопросы