[英]Check if an item is in a nested list
在检查后的简单列表中是微不足道的:
x = [1, 2, 3]
2 in x -> True
但如果是列表清单,例如:
x = [[1, 2, 3], [2, 3, 4]]
2 in x -> False
为了返回True
如何解决这个问题?
试试这个,使用内置的any
功能。 这是最惯用的解决方案,而且效率也很高,因为any
短路并在发现第一场比赛后立即停止:
x = [[1, 2, 3], [2, 3, 4]]
any(2 in sl for sl in x)
=> True
这是一个适用于任何嵌套级别的递归版本。
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
您可以使用set.issubset()
和itertools.chain()
:
In [55]: x = [[1, 2, 3], [2, 3, 4]]
In [56]: {4}.issubset(chain.from_iterable(x))
Out[56]: True
In [57]: {10}.issubset(chain.from_iterable(x))
Out[57]: False
您还可以有效地削减多个项目的成员资格:
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
这可行:
for arr in x:
if 2 in arr:
print True
break
我会推荐Oscar的答案,因为any
选项都是正确的选择。
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的函数(接受的答案)慢。
x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
def find_n(input_list, n):
flat_list = []
for sublist_or_el in input_list:
if isinstance(sublist_or_el, list):
if find_n(sublist_or_el, n) == True:
return True
elif sublist_or_el == n:
return True
return False
print(find_n(x, 6))
快速计时(非常hacky,对不起,今天很忙!):
import time
x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
def a():
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
return (6 in flatten(x))
def b():
def find_n(input_list, n):
flat_list = []
for sublist_or_el in input_list:
if isinstance(sublist_or_el, list):
if find_n(sublist_or_el, n) == True:
return True
elif sublist_or_el == n:
return True
return False
return (find_n(x, 6))
zz = 0
for i in range(100000):
start_time = time.clock()
res = a()
zz += time.clock() - start_time
print(a())
print((zz)/100, "seconds")
zz = 0
for i in range(100000):
start_time = time.clock()
res = b()
zz += time.clock() - start_time
print(b())
print((zz)/100, "seconds")
尝试
2 in [i for sublist in x for i in sublist]
我的代码基于ÓscarLópez的解决方案。 他的解决方案并不是我的问题所需要的,但它给了我足够的信息来解决我的问题。 因此,如果您在一个列表中嵌套了元素,并且需要查看它们是否在另一个嵌套列表中,那么这将起作用。
#!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']
'''
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.