【问题标题】:How to check if a value exists in a list of lists of lists in python?如何检查python中列表列表中是否存在值?
【发布时间】:2021-04-15 04:28:50
【问题描述】:

我有一个列表列表:

lst = [[[1,2,3],[3,4,5]],[1,[2,34,5,[45,67]]]]

我想检查列表中是否存在一个值,例如 67。我已经看过 StackOverflow 问题:

How do I check if a list of lists exists in a list of lists?

但它只显示了一种检查值是否在列表列表中的方法。

无论列表有多深,我将如何搜索列表?

【问题讨论】:

标签: python list


【解决方案1】:

如果您的列表不大并且您想要简单的解决方案,那么您可以将列表转换为字符串并检查该字符串中数字的字符串值,请参见以下示例:

lst = [[[1,2,3],[3,4,5]],[1,[2,34,5,[45,67]]]]
lst1 = str(lst)
print(lst)
print(str(67) in lst1)

输出是:

[[[1, 2, 3], [3, 4, 5]], [1, [2, 34, 5, [45, 67]]]]
True

【讨论】:

  • 不推荐。对于其中包含 67 的任何内容,这将返回 True。 167、267、671。
【解决方案2】:

除了将列表转换为字符串外,您还可以在扁平列表中搜索项目。

要扁平化列表,我们可以使用collections.abc 中的Iterable 类。

from collections.abc import Iterable


def get_flatten(ar):
  if isinstance(ar, Iterable):
    return [inner_iterable for i in ar for inner_iterable in get_flatten(i)]
  return [ar]

def get_searched_result(ar, item):
  return item in get_flatten(ar)


if __name__ == "__main__":
  lst = [[[1,2,3],[3,4,5]],[1,[2,34,5,[45,67]]]]
  item = 67
  print(f"{item} in {lst}: {get_searched_result(lst, item)}")


  item = 32
  print(f"{item} in {lst}: {get_searched_result(lst, item)}")

输出:

67 in [[[1, 2, 3], [3, 4, 5]], [1, [2, 34, 5, [45, 67]]]]: True
32 in [[[1, 2, 3], [3, 4, 5]], [1, [2, 34, 5, [45, 67]]]]: False

参考资料:

【讨论】:

    【解决方案3】:

    另一种没有任何库的嵌套列表的递归方式。一旦找到值,它就会返回。

    def find_nested(lst, val):
      if val in lst:
        return True
      for e in lst:
        if e.__class__ == list and find_nested(e, val):
          return True
      return False
    

    所以,例如:

    lst = [[[1,2,3],[3,4,5]],[1,[2,34,5,[45,67]]],1]
    
    find_nested(lst, 1) #=> True --- it returns at first call
    find_nested(lst, 67) #=> True
    find_nested(lst, 670) #=> False
    
    find_nested(lst, [3,4,5]) #=> True
    

    您可以编辑该方法,使其也返回找到该值的列表。或者放手检查所有返回包含该元素的列表的嵌套列表。或者你需要的任何行为。

    【讨论】:

    • 我会谨慎使用 e.__class__ == listisinstance(e, list),因为还有其他可迭代的类型,例如 tuples,你希望这种代码可以工作跨度>
    【解决方案4】:

    递归。

    from typing import List, Tuple, Any, Union
    
    RecursiveList = Union[List['RecursiveList'], Any]
    
    def multiindex(lst: List[RecursiveList], item) -> Tuple[int]:
        for idx, elem in enumerate(lst):
            if elem == item:
                return (idx,)
            else:
                # try to call it recursively. 
                # if the current element isn't iterable, enumerate() will throw a TypeError
                # which we can just ignore
                try:
                    return (idx,) + multiindex(elem, item)
                except (TypeError, ValueError):
                    continue
        raise ValueError(f'{item} is not in list')
    
    l = [[[1,2,3],[3,4,5]],[1,[2,34,5,[45,67]]]]
    print(multiindex(l, 67))
    # (1, 1, 3, 1)
    

    我们可以通过简单地检查搜索它是否收到 ValueError 来测试是否包含,就像我们使用普通的 list.index() 一样。或者,只需修改方法以返回布尔值而不是抛出 ValueError

    def multicontains(lst: List[RecursiveList], item) -> bool:
        for idx, elem in enumerate(lst):
            if elem == item:
                return True
            else:
                try:
                    sublist_contains = multicontains(elem, item)
                    if sublist_contains:
                        return True
                except TypeError:
                    continue
        return False
    

    【讨论】:

    • 当我运行它时,我得到“回溯(最近一次调用最后一次):文件“./prog.py”,第 3 行,在 NameError: name 'Union' is not defined'。
    • @sasindumaheepala 抱歉,忘记输入 Union。固定的。如果需要,您可以删除注释,它们只是为了清晰起见。
    猜你喜欢
    • 2021-06-02
    • 2015-03-06
    • 1970-01-01
    • 2013-08-07
    • 2017-09-06
    • 1970-01-01
    • 2021-11-15
    • 2017-06-11
    • 1970-01-01
    相关资源
    最近更新 更多