69

在 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/语句(在 python 中)是否与javascriptin中的相同?if()

找到这个问题的答案一直很棘手,因为这in是一个很短的字符串,可以通过搜索引擎缩小答案范围,而且我不知道其操作的正确名称。

4

8 回答 8

139

这取决于是什么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
于 2013-11-04T19:44:32.667 回答
26

使用a in bis 简单地转换为,如果 b 包含 a 或不包含b.__contains__(a),它应该返回。

但是,您的示例看起来有点奇怪,如果输入包含orhow_much ,它会从用户那里获取输入并将其整数值分配给变量。"0""1"

于 2013-11-04T19:44:47.883 回答
14

既然你声称习惯了 JavaScript:

Pythonin运算符类似于 JavaScriptin运算符。

这是一些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!')

对于对象/字典,它们几乎相同,都检查是否1是对象/字典的键。当然,最大的区别在于 JavaScript 是草率的类型,所以'1' in d也是如此。

对于数组/列表,它们非常不同。JS 数组是一个对象,它的索引是键,1 in [3, 4, 5]所以true. Python list 与 dict 完全不同,它的in运算符检查,而不是索引,这往往更有用。Python 将此行为扩展到所有可迭代对象。

有了字符串,它们就更加不同了。JS 字符串不是对象,所以你会得到一个TypeError. 但是 Python strorunicode会检查另一个操作数是否是substring。(这意味着1 in '123'是非法的,因为1不能是任何东西的子字符串,但'1' in '123'它是真的。)

以对象为对象,在 JS 中当然没有区别,但在 Python 中,对象是类的实例,而不是 dict。因此,在 JS 中,1 in d如果一个对象有一个名为 的成员或方法,则它是正确的'1',但在 Python 中,它的含义取决于您的类——Python 将调用d.__contains__(1),然后,如果失败,它会尝试将您的对象用作一个 utterable(通过调用它的__iter__,如果失败,尝试用从 开始的整数对其进行索引0)。

另外,请注意 JS 的in,因为它实际上是检查对象成员,所以执行通常的 JS 方法解析顺序搜索,而 Python 的in,因为它正在检查 dict 的键、序列的成员等,所以没有这样的事情。hasOwnProperty所以,从技术上讲,它可能比操作符更接近方法in

于 2013-11-04T20:08:12.530 回答
3

你习惯使用 javascript if,我假设你知道它是如何工作的。

in是一种实现迭代的Pythonic方式。非程序化思考者应该更容易采用,但讽刺的是,这有时会使程序化思考者更难采用。

当您说 时if x in y,您实际上是在说:

“if xis in y”,它假设y有一个索引。然后在该语句中,根据条件检查if每个索引处的每个对象。y

相似地,

for x in y

遍历x's in yy可索引的项目集在哪里。

以这种方式考虑if这种情况(伪代码):

for i in next:
    if i == "0" || i == "1":
        how_much = int(next)

它会为您完成迭代next

快乐编码!

于 2013-11-04T19:45:48.200 回答
2

也许这些例子将有助于说明什么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
于 2013-11-04T19:45:11.240 回答
2

保留字“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

于 2013-11-04T19:52:19.300 回答
2

这可能是一个很晚的答案。 操作员检查成员资格。也就是说,它检查其左操作数是否是其右操作数的成员。在这种情况下, raw_input() 返回用户在标准输入中提供的str对象。因此,if条件检查输入是否包含子字符串“0”或“1”。考虑到下一行中的类型转换( int() ), if条件实质上检查输入是否包含数字 0 或 1。

于 2018-11-29T13:22:15.593 回答
1

这里raw_inputstring,所以如果你想检查,if var>3那么你应该在 double 旁边转换,即float(next)按照你的方式做if float(next)>3:,但在大多数情况下

于 2013-11-04T19:47:37.557 回答