Возникает вопрос о Idiomatic Python - checking for zero, но этот вопрос также рассматривается с проверкой типа переменных в рамках условий.Объявление множественного условия при проверке на числовой нуль - python
С учетом инструкции стиля 0 if not variable else variable
, это позволит пропустить предмет объекта, например.
>>> x, y = None, []
>>> 0 if not(x and y) else x/y
0
>>> x, y = None, 0
>>> 0 if not(x and y) else x/y
0
>>> x, y = 0, 1
>>> 0 if not(x and y) else x/y
0
>>> x, y = 2, ""
>>> 0 if not(x and y) else x/y
0
>>> x, y = 2, 1
>>> 0 if not(x and y) else x/y
2
Но если я явно проверить значения переменных равным нулю, будет несколько лучше, так как это вызывает ошибку, когда оба типа отличаются или типы, которые не могут быть сопоставлены с нулевым значением, например:
>>> x, y = 2, ""
>>> 0 if (x&y) == 0 else x/y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'int' and 'str'
>>> x,y = "",""
>>> 0 if (x&y) == 0 else x/y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'str' and 'str'
>>> x,y = [],[]
>>> 0 if (x&y) == 0 else x/y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'list' and 'list'
Как правило, при определении условия для проверки на числовое значение что-то вроде кода 0 if (x|y) == 0 else x/y
еще pythonic/более подходящего?
Но это также проблематично, так как это давай логическому тип проскочить и что вызывает некоторые весьма тревожные вещи, как ZeroDivisionError
или ValueError
произойти, например:
>>> x,y = True, True
>>> 0 if (x&y) == 0 else x/y
1
>>> x,y = True, False
>>> 0 if (x&y) == 0 else x/y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> x,y = False, True
>>> 0 if (x&y) == 0 else x/y
0
>>> x,y = False, True
>>> 0 if (x&y) == 0 else math.log(x/y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
Кроме того, это вызывает проблемы, когда типы переменных являются числовыми но несколько иначе:
>>> x, y = 1, 3.
>>> 0 if (x|y) == 0 else math.log(x/y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'int' and 'float'
а также тот факт, что оператор _or
не может принять плавать, это странно:
>>> x, y = 1., 3.
>>> 0 if (x&y) == 0 and type(x) == type(y) == float else math.log(x/y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'float' and 'float'
>>> x, y = 1., 3.
>>> 0 if (x&y) == 0. and type(x) == type(y) == float else math.log(x/y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'float' and 'float'
>>> x, y = 1, 3
>>> 0 if (x&y) == 0 and type(x) == type(y) == float else math.log(x/y)
-1.0986122886681098
Так что вопрос:
- Что такое вещий способ проверить многократные переменный для нулевого значения?
- Кроме того, важно не любить булевский тип slip и поднять ошибку, вместо того чтобы позволить ему вернуть нуль, как это можно сделать?
- И как следует разрешить
TypeError: unsupported operand type(s) for |: 'float' and 'float'
для проверки(x|y) == 0
с x и y как типы с плавающей запятой?
Если у вас есть числовые операции, которые зависят от конкретного типа обоих операндов, очевидное (отсюда вещий) решение либо явно проверить типы обоих операндов или обрабатывать ожидаемые исключения. –
Что касается явной проверки: «0 in (x, y)»? –
@ A.Haaji это не сработает при буле: '0 in (True, False) => True' –