【问题标题】:How to search if dictionary value contains certain string with Python如何使用Python搜索字典值是否包含某些字符串
【发布时间】:2013-06-24 19:45:10
【问题描述】:

我有一本带有键值对的字典。我的值包含字符串。如何搜索字典中是否存在特定字符串并返回与包含该值的键对应的键。

假设我想搜索字典值中是否存在字符串 'Mary' 并获取包含它的键。这是我尝试过的,但显然它不起作用。

#Just an example how the dictionary may look like
myDict = {'age': ['12'], 'address': ['34 Main Street, 212 First Avenue'],
          'firstName': ['Alan', 'Mary-Ann'], 'lastName': ['Stone', 'Lee']}

#Checking if string 'Mary' exists in dictionary value
print 'Mary' in myDict.values()

有没有更好的方法来做到这一点,因为我可能想要查找存储值的子字符串('Mary' 是值'Mary-Ann' 的子字符串)。

【问题讨论】:

    标签: python string dictionary key-value


    【解决方案1】:

    你可以这样做:

    #Just an example how the dictionary may look like
    myDict = {'age': ['12'], 'address': ['34 Main Street, 212 First Avenue'],
          'firstName': ['Alan', 'Mary-Ann'], 'lastName': ['Stone', 'Lee']}
    
    def search(values, searchFor):
        for k in values:
            for v in values[k]:
                if searchFor in v:
                    return k
        return None
    
    #Checking if string 'Mary' exists in dictionary value
    print search(myDict, 'Mary') #prints firstName
    

    【讨论】:

    • 如果假设我有 100 万条记录并且我正在为自动完成搜索实现此功能,那么这将是什么性能问题。
    • @Unknown 你绝对不应该为你的情况这样做。您需要在单独的反向查找字典中索引这些值。
    • 或者,如果您知道字典很大,您可以将其转换为 JSON 并执行正则表达式搜索,例如 pattern = r'\w+(?=": [\S\s][^:]+{})'.format(search_text) 以获取密钥。对于较小的字典不会更快,但对于较大的字典会更快,特别是当数据处于最坏情况时
    【解决方案2】:

    我有点晚了,但另一种方法是使用列表理解和 any 函数,该函数接受一个可迭代并在一个元素为 True 时返回 True

    # Checking if string 'Mary' exists in the lists of the dictionary values
    print any(any('Mary' in s for s in subList) for subList in myDict.values())
    

    如果你想计算其中有“玛丽”的元素的数量,你可以使用sum()

    # Number of sublists containing 'Mary'
    print sum(any('Mary' in s for s in subList) for subList in myDict.values())
    
    # Number of strings containing 'Mary'
    print sum(sum('Mary' in s for s in subList) for subList in myDict.values())
    

    通过这些方法,我们可以轻松地制作函数来检查哪些键或值匹配。

    获取包含'Mary'的键:

    def matchingKeys(dictionary, searchString):
        return [key for key,val in dictionary.items() if any(searchString in s for s in val)]
    

    获取子列表:

    def matchingValues(dictionary, searchString):
        return [val for val in dictionary.values() if any(searchString in s for s in val)]
    

    获取字符串:

    def matchingValues(dictionary, searchString):
        return [s for s i for val in dictionary.values() if any(searchString in s for s in val)]
    

    两者兼得:

    def matchingElements(dictionary, searchString):
        return {key:val for key,val in dictionary.items() if any(searchString in s for s in val)}
    

    如果你只想得到包含“Mary”的字符串,你可以做一个双重列表理解:

    def matchingStrings(dictionary, searchString):
        return [s for val in dictionary.values() for s in val if searchString in s]
    

    【讨论】:

    • 为了获取密钥,根据用户在问题中使用的字典,它会返回此错误消息<ipython-input-7-b5d6370c2444> in <genexpr>(.0) ----> 1 print (sum(1 for key,val in myDict if 'Mary' in val) > 0) ValueError: too many values to unpack (expected 2),并且与matchingKeys 函数<ipython-input-2-65db50c6e286> in <listcomp>(.0) 1 def matchingKeys(dictionary, searchString): ----> 2 return [key for key,val in dictionary if searchString in val] ValueError: too many values to unpack (expected 2) 相同
    • @AndreaCiufo 糟糕,我忘了使用方法dict.items。我想给出这个概念,使用一个行列表理解的想法,但通过重新阅读,我意识到我犯了很多错误
    • 是的,这是因为有一个与键关联的字符串列表,而不是单个字符串:)
    • 没错,我忘了dict.items :) IDK 我在写答案时在想什么,我想我走得太快了
    • @paranormaldist 好吧,您必须将字符串列表或元组作为输入,然后将 dict 的每个字符串与输入中的每个字符串进行比较。所以这意味着将any(searchString in s for s in val) 替换为any(any(searched in s) for s in val for searched in searchString) 或类似的东西。但是只有一行就很长了,所以也许你最好在多行上做或者把它分成函数
    【解决方案3】:

    Klaus 解决方案的开销较小,另一方面,这个解决方案可能更具可读性

    myDict = {'age': ['12'], 'address': ['34 Main Street, 212 First Avenue'],
              'firstName': ['Alan', 'Mary-Ann'], 'lastName': ['Stone', 'Lee']}
    
    def search(myDict, lookup):
        for key, value in myDict.items():
            for v in value:
                if lookup in v:
                    return key
    
    search(myDict, 'Mary')
    

    【讨论】:

      【解决方案4】:
      import re
      for i in range(len(myDict.values())):
           for j in range(len(myDict.values()[i])):
                   match=re.search(r'Mary', myDict.values()[i][j])
                   if match:
                           print match.group() #Mary
                           print myDict.keys()[i] #firstName
                           print myDict.values()[i][j] #Mary-Ann
      

      【讨论】:

        【解决方案5】:
        >>> myDict
        {'lastName': ['Stone', 'Lee'], 'age': ['12'], 'firstName': ['Alan', 'Mary-Ann'],
         'address': ['34 Main Street, 212 First Avenue']}
        
        >>> Set = set()
        
        >>> not ['' for Key, Values in myDict.items() for Value in Values if 'Mary' in Value and Set.add(Key)] and list(Set)
        ['firstName']
        

        【讨论】:

          【解决方案6】:

          对我来说,这也有效:

          def search(myDict, search1):
              search.a=[]
              for key, value in myDict.items():
                  if search1 in value:
                      search.a.append(key)
          
          search(myDict, 'anyName')
          print(search.a)
          
          • search.a 使列表全局可用
          • 如果在任何值中找到匹配的子字符串,则该值的键 值将附加到一个

          【讨论】:

          • 我刚刚了解到,search.a 并不是一种让全球可用的智能方法。目前正在解决,这可能会有所帮助:python-textbok.readthedocs.io/en/1.0/Variables_and_Scope.html
          • def search(myDict, search1): a=[] for key, value in myDict.items(): if search1 in value: a.append(key) return ax=search(myDict, ' anyName') 打印(str(x))
          • def search(myDict, search1): a=[] for key, value in myDict.items(): if search1 in value: a.append(key) return ax=search(myDict, ' anyName') 打印(str(x))
          【解决方案7】:

          以下是接受答案的一条线......(对于一条线爱好者..)

          def search_dict(my_dict,searchFor):
              s_val = [[ k if searchFor in v else None for v in my_dict[k]] for k in my_dict]    
              return s_val
          

          【讨论】:

          • 啊,明白了。您可以像这样在一行中完成:search_dict = lambda x, y: ((k if y in v else None for v in x[k]) for k in x)
          • 我收到一个错误list indices must be integers or slices, not list
          • @AndreaCiufo 给你的代码..我认为你的字典在一个键中包含多个值..
          • 我使用了问题代码,实际上包含一个字符串列表,类似于@Nei 监督here :)
          • @AndreaCiufo 问题现在解决了吗?
          【解决方案8】:
          import re
          for i in range(len(myDict.values())):
              for j in range(len(myDict.values()[i])):
                   match=re.search(r'Mary', myDict.values()[i][j])
                   if match:
                           print match.group() #Mary
                           print myDict.keys()[i] #firstName
                           print myDict.values()[i][j] #Mary-Ann
          

          【讨论】:

            【解决方案9】:
            def search(myDict, lookup):
                a=[]
                for key, value in myDict.items():
                    for v in value:
                        if lookup in v:
                             a.append(key)
                a=list(set(a))
                return a
            

            如果研究涉及更多键,也许您应该创建一个包含所有键的列表

            【讨论】:

              【解决方案10】:

              为使用这篇文章进行类似或更复杂的python字典搜索的其他人提供更通用的解决方案:您可以使用dictpy

              import dictpy
              
              myDict = {'age': ['12'], 'address': ['34 Main Street, 212 First Avenue'],
                        'firstName': ['Alan', 'Mary-Ann'], 'lastName': ['Stone', 'Lee']}
              
              search = dictpy.DictSearch(data=myDict, target='Mary-Ann')
              print(search.result)   # prints -> [firstName.1, 'Mary-Ann']  
              

              列表中的第一个条目是目标位置:字典键“firstName”和列表中的位置 1。第二个条目是搜索返回对象。

              dictpy 的好处是它可以找到多个“Mary-Ann”,而不仅仅是第一个。它会告诉您找到它的位置,您可以搜索更复杂的字典(更多级别的嵌套)并更改返回对象是什么。

              【讨论】:

                【解决方案11】:

                导入 json json.dumps(myDict) 中的“mtach” 如果找到则为真

                【讨论】:

                猜你喜欢
                • 2020-05-01
                • 2011-03-31
                • 1970-01-01
                • 2016-08-09
                • 2010-11-22
                • 2021-11-06
                • 2021-11-01
                相关资源
                最近更新 更多