2012-01-28 1 views
10

Я обычно использую следующие идиомы при работе со словарем Python:Как проверить ключ в defaultdict без обновления словаря (Python)?

try: 
    val = dct[key] 
except KeyError: 
    print key, " is not valid" 

, так как для больших словарей, утверждение

if key in dct: 
    # do something 

не очень эффективно (так что я помню, как читал, но у меня тоже заметили это на практике)

Сегодня я работал с дефолтным делом и на мгновение забыл, что defaultdict никогда не даст вам KeyError, но вместо этого обновит оригинальный словарь.

Как выполнить поиск без обновления defaultdict? Мне действительно нужно распечатать ошибку, чтобы пользователь мог повторно ввести ключ.

Спасибо!

ОБНОВЛЕНИЕ: Несколько плакатов предположили, что мое убеждение, что if key in dct: является медленным, неверно. Я вернулся и проверил книгу, в которой я читал, что лучше использовать try: except:. Это рецепт Python 2002 года, рецепт 1.4 от Alex Martelli, который можно найти также здесь: Add an entry to dictionary. Старые воспоминания настолько ненадежны! В рецепте не упоминается «медленнее», и он даже не использует in, но has_key. Он просто говорит, что try: except: более Pythonic (по крайней мере, книжная версия рецепта). Спасибо за исправление и ответы.

+0

Возможный дубликат http://stackoverflow.com/questions/1602934/what-is-a-good-way-to-test-if-a-key-exists-in-python-dictionary –

+1

Не обман; это о 'defaultdict'. –

+7

'ключ в d' не медленный, период. Если вы говорите иначе, вам лучше иметь надежное доказательство. 'timeit' говорит, что это так же быстро, как и успешный' d [key] ', и намного (почти 10x) быстрее, чем' d [key] '+' except: pass' (предоставленный, он может быть немного быстрее, чем явный ' if', если ключ почти всегда присутствует). Теперь, 'ключ в d.keys()' (Python 2.x) или 'key in list (d.keys()) '(Python 3.x) медленный, но это потому, что он намеренно выбрасывает хэш-таблицу. – delnan

ответ

17

Как выполнить поиск без обновления значения defaultdict?

С key in dct, то есть явно.

Если это действительно слишком дорого для вас (меры, и вы обязательно убедитесь), есть обходные пути для конкретных ситуаций. Например, если значение по умолчанию 'ham' и в некоторых ситуациях вы не хотите хранить (key, 'ham') в defaultdict когда key не найден, то вы можете сделать

dct.get(key, 'ham') # will return dct[key] or 'ham' but never stores anything 
+7

'has_key' устарел в пользу' key in dct' - пожалуйста, не рекламируйте использование старых идиом. – PaulMcG

8

key in dctимеет быть быстрым, говоря, что это медленным было бы сказать, что dct[key] медленный, и этого никогда не должно быть. Извлечение элемента из словаря с его ключевым ключом и тестирование членства в ключе должны быть операциями O (1) в любой достойной реализации словаря, и легко понять, как операция членства может быть реализована с точки зрения операции доступа.

Задать вопрос defaultdict, просто используйте in. И нет никаких оснований избегать использования in в обычном словаре.