Рекомендуется ли использовать условие if ... else для проверки ключей или использовать try ... кроме как для перехвата исключений KeyError в python? - PullRequest
0 голосов
/ 13 января 2020

Итак, скажем, есть словарь var_dict, и я хочу напечатать значение в ключе a, например. Таким образом, один способ будет:

if var_dict is None:
    return
if 'a' not in var_dict.keys():
    return
print(var_dict['a'])

И другой метод будет:

try:
    print(var_dict['a'])
except (KeyError, TypeError):
    return

Мой вопрос, который рекомендуется. Я прочитал здесь: Python: попробуйте - кроме vs if-else - проверить ключи dict , обработка исключений идет медленнее, но что, если мы укажем ожидаемую ошибку? Это так же медленно в этом случае?

Ответы [ 3 ]

3 голосов
/ 13 января 2020

Блок try / кроме действительно медленнее. Я бы сделал это:

def foobar(var_dict):
    return var_dict['a'] if var_dict and 'a' in var_dict else None

Например:

In [1]: def foobar(var_dict):
   ...:      return var_dict['a'] if var_dict and 'a' in var_dict else None
   ...: 

In [2]: 

In [2]: foobar(None)

In [3]: foobar({'x': 1})

In [4]: foobar({'a': 1})
Out[4]: 1

В качестве альтернативы, если вы знаете, что var_dict является словарем (а не None), get() имеет значение по умолчанию:

return var_dict.get('a', None)
2 голосов
/ 13 января 2020
Блок

A try/except для получения ключа или значения по умолчанию будет намного быстрее, чем все другие альтернативы. Например,

from time import time

t = time()
for i in range(1000000):
    v = __builtins__['int'] if 'int' in __builtins__ else None
print(time() - t)

t = time()
for i in range(1000000):
    v = __builtins__.get('int', None)
print(time() - t)

t = time()
for i in range(1000000):
    try:
        v = __builtins__['int']
    except KeyError:
        v = None
print(time() - t)

Результаты:

0.12224698066711426
0.15873217582702637
0.0927286148071289

Первый намного медленнее, потому что Python в основном получает ключ дважды. Один раз через __contains__, затем __getitem__. Второй медленнее, потому что Python выполняет некоторую внутреннюю проверку, в то время как try/catch идет прямо к точке или неудаче.

Проще просить прощения, чем разрешения.

0 голосов
/ 13 января 2020

Используйте второй метод. Из Python Глоссарий :

EAFP :
Проще просить прощения, чем разрешения. Этот общий стиль кодирования Python предполагает наличие допустимых ключей или атрибутов и перехватывает исключения, если предположение оказывается ложным. Этот чистый и быстрый стиль характеризуется наличием множества попыток, кроме заявлений. Техника контрастирует со стилем LBYL, общим для многих других языков, таких как C.

Просто чтобы быть уверенным, я просто попробовал использовать команду %% timeit magi c в jupyter и второй вариант немного быстрее.

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