Python 检查项目是否在嵌套列表中

Python 检查项目是否在嵌套列表中,python,list,Python,List,在一个简单的列表中,以下检查很简单: x = [1, 2, 3] 2 in x -> True 但如果是列表列表,例如: x = [[1, 2, 3], [2, 3, 4]] 2 in x -> False 如何解决此问题才能返回True?使用内置函数尝试此操作。这是最惯用的解决方案,也是最有效的解决方案,因为any一旦找到第一个匹配项,就会短路并停止: x = [[1, 2, 3], [2, 3, 4]] any(2 in sl for sl in x) =>

在一个简单的列表中,以下检查很简单:

x = [1, 2, 3]

2 in x  -> True
但如果是列表列表,例如:

x = [[1, 2, 3], [2, 3, 4]]

2 in x   -> False

如何解决此问题才能返回
True

使用内置函数尝试此操作。这是最惯用的解决方案,也是最有效的解决方案,因为
any
一旦找到第一个匹配项,就会短路并停止:

x = [[1, 2, 3], [2, 3, 4]]
any(2 in sl for sl in x)
=> True
这将有助于:

for arr in x:
    if 2 in arr:
        print True
        break

我推荐Oscar的答案,因为
any
是正确的选择。

您可以使用
set.issubset()
itertools.chain()

您还可以有效地检查多个项目的成员资格:

In [70]: {2, 4}.issubset(chain.from_iterable(x))
Out[70]: True

In [71]: {2, 4, 10}.issubset(chain.from_iterable(x))
Out[71]: False

这是一个递归版本,适用于任何级别的嵌套

def in_nested_list(my_list, item):
    """
    Determines if an item is in my_list, even if nested in a lower-level list.
    """
    if item in my_list:
        return True
    else:
        return any(in_nested_list(sublist, item) for sublist in my_list if isinstance(sublist, list))
以下是一些测试:

x = [1, 3, [1, 2, 3], [2, 3, 4], [3, 4, [], [2, 3, 'a']]]
print in_nested_list(x, 2)
print in_nested_list(x, 5)
print in_nested_list(x, 'a')
print in_nested_list(x, 'b')
print in_nested_list(x, [])
print in_nested_list(x, [1, 2])
print in_nested_list(x, [1, 2, 3])

True
False
True
False
True
False
True
TL;DR

x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
def find_n(input_list, n):
    for el in input_list:
        if el == n or (isinstance(el, list) and find_n(el, n)):
            return True
    return False
print(find_n(x, 6))
请注意,有点有趣的是:

def find_n(input_list, n):
    return any([el == n or (isinstance(el, list) and find_n(el, n)) for el in input_list])
return (find_n(x, 6))
执行速度慢50%以上

原始答案

如果深度大于2怎么办?以下是一种处理一般情况的方法:

x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]

def flatten(input_list):
    flat_list = []
    for sublist_or_el in input_list:
        if isinstance(sublist_or_el, list):
            for sublist_or_el2 in flatten(sublist_or_el):
                flat_list.append(sublist_or_el2)
        else:
            flat_list.append(sublist_or_el)
    return flat_list

print(6 in flatten(x))
虽然不确定速度,但正如我所说,这是一种可能对某人有用的方法

编辑-更好(更快)的回答:

通过提前返回,这减少了所花费的时间(如果找到
n
,实际上即使找不到,也大约是实际时间的一半…)。这比@Curt F.的答案略快,比创建假定最大深度为2的函数(接受的答案)要慢


快速计时(非常烦人,抱歉,今天很忙!):

试一试


我的代码基于奥斯卡·洛佩斯的解决方案。他的解决方案并不是我解决问题所需要的,但它为我提供了足够的信息来解决我的问题。所以,如果您在一个列表中有嵌套的元素,并且需要查看它们是否在另一个嵌套列表中,这将起作用

#!python2

lst1 = [['a', '1'], ['b', '2'], ['c', '3'], ['d', '4'], ['e', '5']]
lst2 = [['b', '2'], ['d', '4'], ['f', '6'], ['h', '8'], ['j', '10'], ['l', '12'], ['n', '14']]

# comparing by index 0, prints lst1 items that aren't in lst2
for i in lst1:
    if not any(i[0] in sublst for sublst in lst2):
        print i
'''
['a', '1']
['c', '3']
['e', '5']
'''

print

# comparing by index 0, prints lst2 items that aren't in lst1
for i in lst2:
    if not any(i[0] in sublst for sublst in lst1):
        print i
'''
['f', '6']
['h', '8']
['j', '10']
['l', '12']
['n', '14']
'''
答案太棒了!我建议使用它

但是,您可以使用itertools展平列表并对其求值,以便:

import itertools

x = [[1, 2, 3], [2, 3, 4]]
2 in itertools.chain.from_iterable(x)

Output: True
此外,您还可以通过理解“手动”完成:

x = [[1, 2, 3], [2, 3, 4]]
2 in [item for sub_list in x for item in sub_list]

Output: True

这些只是其他方法,祝你好运。

除非元素恰好位于最后一个子列表中,否则这不会起作用。。。此外,应短路,以防提前发现元件。这就是这里需要的
任何
,请看我的答案。刚刚测试过,它也能工作,即使它不在最后一个子列表中。不,它不在。用
x=[[3,3],[4,4]]
测试它,它会工作,即使它不应该工作。在这种情况下,sl是什么?只是一个变量名,它代表“子列表”。您的解决方案并不完全符合我的需要,但它提供了足够的信息让我解决问题。我公布了我问题的解决方案。它打印出不在另一个嵌套列表中的嵌套元素。为什么不只打印chain.from_iterable(x)中的
4,并避免为单个元素测试用例设置
set
<毕竟,
中的code>in可以处理任意的iterables,短路很好,不需要散列元素。向上投票不考虑(
chain
是一个很好的解决方案)。@ShadowRanger当然,如果是一次性(少量)操作,则无需转换为set。谢谢你的提醒。
 2 in [i for sublist in x  for i in sublist]
#!python2

lst1 = [['a', '1'], ['b', '2'], ['c', '3'], ['d', '4'], ['e', '5']]
lst2 = [['b', '2'], ['d', '4'], ['f', '6'], ['h', '8'], ['j', '10'], ['l', '12'], ['n', '14']]

# comparing by index 0, prints lst1 items that aren't in lst2
for i in lst1:
    if not any(i[0] in sublst for sublst in lst2):
        print i
'''
['a', '1']
['c', '3']
['e', '5']
'''

print

# comparing by index 0, prints lst2 items that aren't in lst1
for i in lst2:
    if not any(i[0] in sublst for sublst in lst1):
        print i
'''
['f', '6']
['h', '8']
['j', '10']
['l', '12']
['n', '14']
'''
import itertools

x = [[1, 2, 3], [2, 3, 4]]
2 in itertools.chain.from_iterable(x)

Output: True
x = [[1, 2, 3], [2, 3, 4]]
2 in [item for sub_list in x for item in sub_list]

Output: True