【问题标题】:what's the different between "is True" and "== True" and when to use each?“is True”和“== True”之间有什么区别以及何时使用它们?
【发布时间】:2020-04-29 01:53:02
【问题描述】:

问题在标题中。 我有一个键的字典,每个键值为 True 或 False 我有一个项目清单。 我想遍历 dict,并检查 if (key in list) == (or is) dict[key]

这意味着我想看看我将从“in”调用中获得的返回值与字典中的值是否匹配,

例如:

quick_dict = dict()
quick_list = list()
quick_dict['hi'] = True
quick_dict["hello"] = True
quick_dict["bye"] = False
quick_dict["bi"] = False
quick_dict['zi'] = True
quick_dict["zv"] = True


quick_list.append("hi")
quick_list.append("bye")
for key in quick_dict:
    if (key in quick_list) == quick_dict[key]:
        print(key)

在这种情况下我应该使用哪一个?总的来说,这种情况有什么不同?

【问题讨论】:

标签: python


【解决方案1】:

我们看下面的代码:

x, y = True, True
u, v = [True], [True]

print(x is y)
print(u is v)

>>> True
>>> False

使用is 时,会增加一层复杂性,因为您要处理变量是如何写入内存的。我们可以看到True在内存中存储了一次。所以xy 在我们调用变量时会访问同一块内存。

相反,当我们创建列表时,Python 会在内存中分配两个不同的位置,每个列表一个位置。这意味着在示例代码运行之后,我们存储了 True、[True] 和 [True]。

在您的示例中,TrueFalse 在内存中写入一次,无论我们将它们分配给变量多少次。

Variables:      x  y     u     v
                 \/      |     |
Memory:         True  [True] [True]

【讨论】:

    【解决方案2】:

    一般来说,您不想使用is== 测试布尔变量。只需说 if ... 或将其单独放入布尔表达式中。

    你想测试2个条件,看来:

    1. 是两个集合中的键
    2. dict[key] 是否为真

    所以,你应该写

    if key in quick_list and quick_dict[key]:
        # do something
    

    如果这些列表或字典“很大”,您应该只使用集合表示法,然后仅对 2 个集合的交集进行迭代,这会自动处理第一个条件并将循环缩短到 2 个集合的交集喜欢:

    In [4]: quick_set = {1, 3, 5}                                                   
    
    In [5]: quick_dict = {1: True, 2: True, 3: False, 4: True}                      
    
    In [6]: matched_keys = quick_set.intersection(set(quick_dict.keys()))           
    
    In [7]: for k in matched_keys: 
       ...:     if quick_dict[k] : print(k, quick_dict[k]) 
       ...:                                                                         
    1 True
    

    【讨论】:

      【解决方案3】:

      在 Python 中,TrueFalse(还有 None)被称为单例对象。它们在该过程中存在一次且仅一次。对这些值的任何分配都将始终分配给同一个对象。所以这意味着分配给True 的任何变量都是True 的相同版本(因为只有一个版本)。

      x = True
      y = True
      x is y
      # True
      (x is y) is True
      # True
      

      通常,您不会在问题中使用这两种语法。如果要检查值是否为True,只需按原样传递即可:

      x = True
      if x:
          print('hello world')
      

      这比:

      x = True
      if x == True:
          print('i am a computer')
      

      因为您要添加不需要进行的附加评估。在上面的示例中,Python 将 x == True 评估为 True,然后评估 if True 以继续 if 块。

      除了....

      我看到的一个例外是有时您希望代码接受字符串或布尔值,并根据传递的内容做出决定。 Matplotlib 有一点。在这种情况下,您可以使用x is True

      这是一个接受字符串或布尔值的版本号松散器示例。

      def format_version(version, how):
          allowed = ('full', 'major', 'minor', 'none', 'true', 'false', True, False)
          if how not in allowed
              raise ValueError(
                  "Argument `how` only accepts the following values: {}".format(allowed)
              )
      
          n = version.count('.')
          if (n == 0) or (how=='full') or (how is True):
              return version
          if n == 1:
              major, minor = version.split('.')
              subs = ''
          if version.count('.') >= 2:
              major, minor, subs = version.split('.', 2)
      
          if how == 'major':
              return major + '.*'
          if how == 'minor':
              if not subs:
                  return '{0}.{1}'.format(major, minor)
              return '{0}.{1}.*'.format(major, minor)
      

      这里专门检查True 是否通过,因为对字符串的简单布尔检查也将是真的。需要明确的是,这不是一个好的模式,它只是因为您希望您的用户能够传递 True/False 值而发生。

      处理这种情况的更好方法是转换为字符串,然后检查字符串。像这样:

      def format_version(version, how):
          how = str(how).lower()
          allowed = ('full', 'major', 'minor', 'none', 'true', 'false')
          if how not in allowed
              raise ValueError(
                  "Argument `how` only accepts the following values: {}".format(allowed)
              )
      
          n = version.count('.')
          if (n == 0) or (how == 'full') or (how == 'true'):
              return version
          if n == 1:
              major, minor = version.split('.')
              subs = ''
          if version.count('.') >= 2:
              major, minor, subs = version.split('.', 2)
      
          if how == 'major':
              return major + '.*'
          if how == 'minor':
              if not subs:
                  return '{0}.{1}'.format(major, minor)
              return '{0}.{1}.*'.format(major, minor)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-18
        • 2021-05-13
        • 1970-01-01
        • 1970-01-01
        • 2016-10-17
        • 2020-05-02
        • 2016-03-21
        • 2011-10-15
        相关资源
        最近更新 更多