【问题标题】:How to check if a key-value pair is present in a dictionary?如何检查字典中是否存在键值对?
【发布时间】:2016-03-20 07:38:02
【问题描述】:

是否有一种智能的 Pythonic 方法来检查字典中是否存在项目(键、值)?

a={'a':1,'b':2,'c':3}
b={'a':1}
c={'a':2}

b in a:
--> True
c in a:
--> False

【问题讨论】:

标签: python python-2.7 dictionary


【解决方案1】:

对于 python 3.x 使用 if key in dict

查看示例代码

#!/usr/bin/python
a={'a':1,'b':2,'c':3}
b={'a':1}
c={'a':2}
mylist = [a, b, c]
for obj in mylist:
    if 'b' in obj:
        print(obj['b'])


Output: 2

【讨论】:

    【解决方案2】:

    使用.get 通常是检查键值对是否存在的最佳方法。

    if my_dict.get('some_key'):
      # Do something
    

    有一个警告,如果密钥存在但它是虚假的,那么它将无法通过测试,这可能不是你想要的。请记住,这种情况很少见。现在逆是一个更常见的问题。那就是使用in 来测试密钥的存在。我在读取csv文件时经常发现这个问题。

    例子

    # csv looks something like this:
    a,b
    1,1
    1,
    
    # now the code
    import csv
    with open('path/to/file', 'r') as fh:
      reader = csv.DictReader(fh) # reader is basically a list of dicts
      for row_d in reader:
        if 'b' in row_d:
          # On the second iteration of this loop, b maps to the empty string but
          # passes this condition statement, most of the time you won't want 
          # this. Using .get would be better for most things here. 
    

    【讨论】:

      【解决方案3】:

      将我的评论转化为答案:

      使用已经作为内置方法提供的dict.get 方法(我认为是最pythonic)

      >>> dict = {'Name': 'Anakin', 'Age': 27}
      >>> dict.get('Age')
      27
      >>> dict.get('Gender', 'None')
      'None'
      >>>
      

      根据文档 -

      get(key, 默认) - 如果键在字典中,则返回键的值,否则返回默认值。 如果没有给出default,则默认为None,这样这个方法 从不引发 KeyError。

      【讨论】:

        【解决方案4】:
        >>> a = {'a': 1, 'b': 2, 'c': 3}
        >>> b = {'a': 1}
        >>> c = {'a': 2}
        

        首先是一种适用于 Python2 Python3

        的方法
        >>> all(k in a and a[k] == b[k] for k in b)
        True
        >>> all(k in a and a[k] == c[k] for k in c)
        False
        

        在 Python3 中也可以使用

        >>> b.items() <= a.items()
        True
        >>> c.items() <= a.items()
        False
        

        对于 Python2,等价于

        >>> b.viewitems() <= a.viewitems()
        True
        >>> c.viewitems() <= a.viewitems()
        False
        

        【讨论】:

        • if k in a 检查意味着all 检查将报告{'d': 4} 作为a 的子集。
        【解决方案5】:
           a.get('a') == 1
        => True
           a.get('a') == 2
        => False
        

        如果None 是有效项目:

        {'x': None}.get('x', object()) is None
        

        【讨论】:

          【解决方案6】:

          使用get:

          # this doesn't work if `None` is a possible value
          # but you can use a different sentinal value in that case
          a.get('a') == 1
          

          使用 try/except:

          # more verbose than using `get`, but more foolproof also
          a = {'a':1,'b':2,'c':3}
          try:
              has_item = a['a'] == 1
          except KeyError:
              has_item = False
          
          print(has_item)
          

          在 Python3 中建议 items 和在 Python 2.7 中建议 viewitems 的其他答案更易于阅读且更惯用,但此答案中的建议在没有任何兼容性代码的 Python 版本中均有效,并且仍会在恒定时间内运行。选择你的毒药。

          【讨论】:

            【解决方案7】:

            您已标记此 2.7,而不是 2.x,因此您可以检查元组是否在字典的 viewitems 中:

            (key, value) in d.viewitems()
            

            在幕后,这基本上是key in d and d[key] == value

            在 Python 3 中,viewitems 只是 items,但不要在 Python 2 中使用 items!这将建立一个列表并进行线性搜索,花费 O(n) 的时间和空间来进行本应为 O(1) 的快速检查。

            【讨论】:

            • Python2.x 中的 iteritems 在 Python3 中不被视为 items 吗?文档说viewitems 是一个动态视图对象。
            • @cricket_007:不,Python 2 中的iteritems 没有 Python 3 等效项。 Python 3 的 items 是一个动态视图对象,类似于 Python 2.7 的 viewitems
            • 我投了赞成票,因为这是 python 2.7。然而,这只是对 python 2.6 的警告,这是行不通的。
            【解决方案8】:

            您可以对照字典的.items() 检查键、值的元组。

            test = {'a': 1, 'b': 2}
            print(('a', 1) in test.items())
            >>> True
            

            【讨论】:

            • 这真的很慢,因为它构建了一个项目列表并在列表中进行线性搜索。
            • @user2357112 是的。如果它是程序的性能关键部分,我会选择 Bhargav Rao 的答案,但我认为这更具可读性。
            • iteritems() 会更快吗?我的意思是,仍然是线性搜索,但在记忆方面,它是一个生成器。
            • @cricket_007 我不知道。 Python 3 没有iteritems()
            • 当一个选项是 O(n),另一个选项是 O(1),并且两个选项都是 1-liners 时,任何可读性增益都是不值得的。
            【解决方案9】:

            使用and 的短路属性。这样如果左手为假,则在检查值时不会得到KeyError

            >>> a={'a':1,'b':2,'c':3}
            >>> key,value = 'c',3                # Key and value present
            >>> key in a and value == a[key]
            True
            >>> key,value = 'b',3                # value absent
            >>> key in a and value == a[key]
            False
            >>> key,value = 'z',3                # Key absent
            >>> key in a and value == a[key]
            False
            

            【讨论】:

            • @GingerPlusPlus,因为它更快
            • @GingerPlusPlus:当None 是有效的dict 值时,它可以避免使用显式标记值的麻烦。另外,查找get 无论如何都是字典查找。
            • @GingerPlusPlus,如果b={'a':None} 等你会遇到问题,除非你使用a.get(k, object()) 来确保没有错误的平等。
            • @GingerPlusPlus:使用get 需要额外查找才能找到get 方法,甚至在您调用它之前。
            • @GingerPlusPlus,我之前也为类似的问题计时过,肯定更快
            猜你喜欢
            • 2012-03-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多