【问题标题】:Use and meaning of "in" in an if statement?if语句中“in”的用法和含义?
【发布时间】:2013-11-04 19:40:43
【问题描述】:

在 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 中)是否与在 javascript 中的 if() 相同?

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

【问题讨论】:

  • 使用运算符搜索 Google 也可能会有所帮助——例如,python "in" operator 在前几个结果中准确给出了您需要的内容。
  • 在最近的 Pythons (2.6+) 上,你不应该使用 next 作为变量名。您将覆盖内置函数next
  • 如果你用过 JavaScript,你怎么会不知道它还有一个in 运算符?
  • @Scherf:嗯,它“连接”到 if 语句的方式与 > 或任何其他运算符的方式相同……并且与 JavaScript 中的方式相同。

标签: python


【解决方案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

【讨论】:

  • 或自定义类__contains__方法;P
  • 您是否必须编写一个 lambda 函数将 "in" in ["indigo", "violet"] 更改为 True 以匹配“indigo”中的“in”?
  • @sinekonata: any('in' in item for item in ['indigo', 'violet']) 就足够了。
【解决方案2】:

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

但是,您的示例看起来有点奇怪,它接受用户输入并将其整数值分配给how_much 变量如果输入包含"0""1"

【讨论】:

  • "如果输入包含1或2";为什么是 1 或 2,而不是 1 或 0?为了我自己的缘故,“包含”字面意思是如果字符串中有任何一个数字,那么表达式是真的?
  • 我的错误,我看错了,当然应该是 1 或 0。实际上,如果给定的字符串是子字符串(如其他人提到的),则包含检查(针对字符串)。那里有两个电话:if next.__contains__("0") or next.__contains__("1"):
  • +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!')

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

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

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

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

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

【讨论】:

    【解决方案4】:

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

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

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

    “如果xy 中”,它假定y 有一个索引。然后在if 语句中,根据条件检查y 中每个索引处的每个对象。

    同样,

    for x in y

    遍历y 中的x,其中y 是可索引的项目集。

    这样想if的情况(伪代码):

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

    它会为您处理next 的迭代。

    编码愉快!

    【讨论】:

      【解决方案5】:

      也许这些示例将有助于说明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
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • raw_input 保证返回一个str,它是可迭代的,所以你不需要猜测它是否返回一个可迭代的对象。
        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          这里raw_inputstring,所以如果你想检查if var&gt;3,那么你应该在double 旁边转换,即float(next) 并像if float(next)&gt;3: 那样做,但在大多数情况下

          【讨论】:

            猜你喜欢
            • 2018-04-15
            • 2022-01-25
            • 1970-01-01
            • 2021-08-06
            • 2013-06-20
            • 1970-01-01
            • 2017-08-14
            • 2016-12-29
            • 1970-01-01
            相关资源
            最近更新 更多