【问题标题】: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 str 或 unicode 将检查另一个操作数是否是 子字符串。 (这意味着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 时,您实际上是在说:

    “如果x 在y 中”,它假定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_input 是string,所以如果你想检查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
            相关资源
            最近更新 更多