【问题标题】:How can I deep search a Python list?如何深度搜索 Python 列表?
【发布时间】:2013-02-23 22:22:42
【问题描述】:

我想在 Python 中的列表中进行深度搜索。比如我想知道5在my_list中与否。

my_list = [2, [3, 4, [2, 3]], 1, [4, [5]]]

我该怎么做?

【问题讨论】:

    标签: python search arraylist


    【解决方案1】:

    不确定使用多层嵌套的快速方法,但是像这样的递归算法可以解决问题:

    def nestedSearch(nested, v):
        for element in nested:
            if isinstance(element, list):
                if nestedSearch(element, v):
                    return True
            elif element == v:
                return True
        return False
    

    你也可以看看这个扁平化多嵌套列表:

    Recursive generator for flattening nested lists

    【讨论】:

      【解决方案2】:

      您可以将flatten function(将其视为itertools.chain 的递归版本)与Python 的标准in 运算符(在生成器上进行线性搜索)结合起来得到:

      >>> def flatten(nested):
          try:
              for sublist in nested:
                  for element in flatten(sublist):
                      yield element
          except TypeError:
              yield nested
      
      
      >>> my_list = [2, [3, 4, [2, 3]], 1, [4, [5]]]
      >>> 5 in flatten(my_list)
      True
      

      根据链接问题中的 cmets,如果您要搜索的内容是可迭代的,您将需要优化 flatten 代码 - 例如,元组将像列表一样被展平到搜索中,并且搜索字符串递归直到它达到了 Python 的堆栈限制。

      【讨论】:

        【解决方案3】:

        如果你有一个列表列表,你可以使用这种方法

        >>> l = [[1,2,3],[4,5,6], [7], [8,9]]
        >>> [item for sublist in l for item in sublist]
        [1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> 5 in [item for sublist in l for item in sublist]
        True
        

        首先将列表展平,然后使用 O(n) 进行搜索。

        如果你的列表看起来像你的例子,我想不出另一种方法来 这样做比使用 for 循环...

        【讨论】:

        • 这仅在您正在展平一个级别的列表时才有效,并且每个元素都保证是可迭代的并且不是搜索的可能匹配项。在这种情况下,5 in itertools.chain.from_iterable(l) 可能比列表推导更清晰,当然也更快(因为它不会构建仅用于一次搜索的完整列表)。
        • 这就是我说的(或打算说的 :-) 见stackoverflow.com/questions/952914/…
        • 请注意,该问题的已接受答案中的 cmets 声称 list(itertools.chain.from_iterable(l) 比列表理解更快。您实际上并不需要一个列表来进行搜索(in 在任何可迭代对象上都可以正常工作)这一事实只会复合。
        【解决方案4】:

        一种方法:

        def deapSearch(searchElement, searchList):
            for element in searchList:
                if element == searchElement:
                    return True
                elif type(element) == type(list):
                    found = deapSearch(searchElement, element)
                    if found:
                        return found
            return False
        deapSearch(5, my_list)
        True
        deapSearch(4, my_list)
        True
        

        不漂亮但工作。

        【讨论】:

          【解决方案5】:

          我最近需要这样做并且需要一个简单的解决方案。所以我将它添加为一种快速而肮脏的方式来展平/搜索列表(可能不是一个完美的解决方案,但它对我有用)。

          >>> my_list = [2, [3, 4, [2, 3]], 1, [4, [5]]]
          >>> str(5) in str(my_list) # returns True
          >>> str(my_list).find(str(5)) # returns the index
          

          编辑:也添加一个正则表达式解决方案。但是如果你有更复杂的情况,那么你不妨遍历列表。

          >>> import re
          >>> str(5) in re.findall('(?<=[,\[])([ a-zA-Z0-9 ]+)(?=[,\]])', str(my_list))
          

          正则表达式本质上是扁平化列表,但不适用于列表项中的特殊字符。

          【讨论】:

          • str(5) in str([1, [2, 15]]) # =&gt; True 你的方法不对。你至少需要一个正则表达式。
          【解决方案6】:

          如果您只有一个包含整数或字符的嵌套列表,解决此问题的一种方法是创建一个没有所有不需要元素的列表(没有 '[' , ']' ...):

          假设我们有一个带有字符的嵌套列表:

          >>> nested = [[[[['F', 'B'], 'G'], ['D', 'A']], 'C'], 'E']
          >>> string = str(nested)
          >>> string = string.replace('[','',len(string))
          >>> string = string.replace(']','',len(string))
          >>> string = string.replace("'","",len(string))
          >>> string = string.replace(" ","",len(string))
          >>> string = string.split(',')
          

          它给出了:

          >>> print (string)
          ['F', 'B', 'G', 'D', 'A', 'C', 'E']
          

          现在您可以轻松搜索,无需任何循环:

          >>> 'F' in string
          True
          

          【讨论】:

          • 您必须考虑的一件事是整数嵌套列表在内存中比简单字符串更昂贵,并且由于迭代,递归函数不是处理此类问题的最简单方法深度限制。使用 Python 的一大优势是您可以像在列表中搜索一样在字符串中搜索
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-09
          • 1970-01-01
          • 2014-01-12
          • 2015-10-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多