Как проверить ключ в defaultdict без обновления словаря (Python)?

Обычно я использую следующую идиому при работе с словарем Python:

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

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

if key in dct:
    # do something

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

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

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

Спасибо!

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

Ответ 1

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

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

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

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

Ответ 2

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

Для вашего вопроса с defaultdict просто используйте in. И нет никаких оснований избегать использования in в нормальном словаре.