Использование и значение "in" в выражении if?
В примере из Zed Shaw Learn Python the Hard Way в одном из упражнений отображается следующий код:
next = raw_input("> ")
if "0" in next or "1" in next:
how_much = int(next)
Мне сложно понять значение in
в этом утверждении. Я привык использовать операторы if
, например, в javascript, где синтаксис выглядит примерно так:
var = 5;
if (var > 3) {
//code to be executed
}
Является ли этот оператор if
/in
(в python) таким же, как if()
в javascript?
Нахождение ответа на это было сложно, потому что in
- это такая короткая строка, которая сужает ответ через поисковую систему, и я не знаю, как правильно его использовать.
Ответы
Ответ 1
Это зависит от того, что next
.
Если это строка (как в вашем примере), то in
проверяет подстроки.
>>> "in" in "indigo"
True
>>> "in" in "violet"
False
>>> "0" in "10"
True
>>> "1" in "10"
True
Если это другой тип итерации (список, кортеж, словарь...), то in
проверяет принадлежность.
>>> "in" in ["in", "out"]
True
>>> "in" in ["indigo", "violet"]
False
В словаре членство рассматривается как "один из ключей":
>>> "in" in {"in": "out"}
True
>>> "in" in {"out": "in"}
False
Ответ 2
Использование a in b
просто переводит на b.__contains__(a)
, который должен возвращаться, если b включает a или нет.
Но ваш пример выглядит немного странным, он берет ввод от пользователя и присваивает его целочисленное значение переменной how_much
, если вход содержит "0"
или "1"
.
Ответ 3
Поскольку вы утверждаете, что используете JavaScript:
Оператор Python in
похож на JavaScript in
.
Вот несколько JavaScript:
var d = {1: 2, 3: 4};
if (1 in d) {
alert('true!');
}
И эквивалентный Python:
d = {1: 2, 3: 4}
if 1 in d:
print('true!')
С объектами /dicts они почти идентичны, проверяя, является ли 1
ключом объекта /dict. Большая разница, конечно, в том, что JavaScript небрежно напечатан, поэтому '1' in d
будет таким же правдивым.
С массивами/списками они очень разные. Массив JS - это объект, а его индексы - это ключи, поэтому 1 in [3, 4, 5]
будет true
. Список Python полностью отличается от dict, а его оператор in
проверяет значения, а не индексы, которые, как правило, более полезны. И Python распространяет это поведение на все итерации.
С помощью строк они еще более разные. Строка JS не является объектом, поэтому вы получите TypeError
. Но Python str
или unicode
проверяет, является ли другой операнд подстрокой. (Это означает, что 1 in '123'
является незаконным, поскольку 1
не может быть подстрокой чего-либо, но '1' in '123'
является истинным.)
С объектами как объектами, в JS, конечно, нет различия, но в Python объекты являются экземплярами классов, а не dicts. Таким образом, в JS 1 in d
будет истинным для объекта, если у него есть член или метод с именем '1'
, но в Python он соответствует вашему классу, что это значит, - Python вызовет d.__contains__(1)
, тогда, если это не работает, он пытается использовать ваш объект как utterable (вызывая его __iter__
, и если это не удается, попробуйте индексировать его целыми числами, начиная с 0
).
Кроме того, обратите внимание, что JS in
, поскольку он фактически проверяет принадлежность объекта, выполняет обычный поиск по порядку JS-метода-запроса, а Python in
, потому что он проверяет ключи dict, члены последовательности и т.д., не делает такой вещи. Таким образом, технически это, вероятно, немного ближе к методу hasOwnProperty
, чем к оператору in
.
Ответ 4
Возможно, эти примеры помогут проиллюстрировать, что делает in
. В основном это означает Is this item in this other item?
listOfNums = [ 1, 2, 3, 4, 5, 6, 45, 'j' ]
>>> 3 in listOfNums:
>>> True
>>> 'j' in listOfNums:
>>> True
>>> 66 in listOfNums:
>>> False
Ответ 5
Вы привыкли использовать javascript if
, и я предполагаю, что вы знаете, как это работает.
in
является питоновским способом реализации итерации. Это должно быть проще для не-программных мыслителей, но это может иногда усложнять программистам мыслить, иронично.
Когда вы говорите if x in y
, вы буквально говорите:
", если x
находится в y
", что предполагает, что y
имеет индекс. В этом выражении if
затем каждый объект в каждом индексе в y
проверяется на условие.
Аналогично,
for x in y
выполняет итерацию через x
в y
, где y
- это индексируемый набор элементов.
Подумайте о ситуации if
таким образом (псевдокод):
for i in next:
if i == "0" || i == "1":
how_much = int(next)
Он позаботится об итерации над next
для вас.
Счастливое кодирование!
Ответ 6
Здесь raw_input
есть string
, поэтому, если вы хотите проверить, if var>3
, тогда вы должны преобразовать double в double, т.е. float(next)
и сделать так, как вы бы сделали if float(next)>3
:, но в большинстве случаев
Ответ 7
зарезервированное слово "in" используется для просмотра внутри объекта, который может быть повторен.
list_obj = ['a', 'b', 'c']
tuple_obj = ('a', 1, 2.0)
dict_obj = {'a': 1, 'b': 2.0}
obj_to_find = 'c'
if obj_to_find in list_obj:
print('Object {0} is in {1}'.format(obj_to_find, list_obj))
obj_to_find = 2.0
if obj_to_find in tuple_obj:
print('Object {0} is in {1}'.format(obj_to_find, tuple_obj))
obj_to_find = 'b'
if obj_to_find in dict_obj:
print('Object {0} is in {1}'.format(obj_to_find, dict_obj))
Вывод:
Object c is in ['a', 'b', 'c']
Object 2.0 is in ('a', 1, 2.0)
Object b is in {'a': 1, 'b': 2.0}
Однако
cannot_iterate_over = 5.5
obj_to_find = 5.5
if obj_to_find in cannot_iterate_over:
print('Object {0} is in {1}'.format(obj_to_find, cannot_iterate_over))
будет бросать
Traceback (most recent call last):
File "/home/jgranger/workspace/sandbox/src/csv_file_creator.py", line 43, in <module>
if obj_to_find in cannot_iterate_over:
TypeError: argument of type 'float' is not iterable
В вашем случае raw_input ( " > " ) возвращает итерируемый объект или он будет бросать TypeError