如何深度搜索 Python 列表?

Posted

技术标签:

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

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

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

我该怎么做?

【问题讨论】:

【参考方案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) 可能比列表推导更清晰,当然也更快(因为它不会构建仅用于一次搜索的完整列表)。 这就是我说的(或打算说的 :-) 见***.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 的一大优势是您可以像在列表中搜索一样在字符串中搜索

以上是关于如何深度搜索 Python 列表?的主要内容,如果未能解决你的问题,请参考以下文章

Python算法-深度优先搜索&广度优先搜索(DFS&BFS)

第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理

Python | 一文简单看懂 深度&广度 优先算法

Python|一文简单看懂 深度&广度 优先算法

广度/深度优先搜索算法 - python实现

Python|DFS(深度优先搜索)介绍