if列表的布尔表达式在其他列表中

时间:2016-08-11 00:47:09

标签: python list contains sub-array

检查列表是否在另一个列表中的有效方法是什么?类似的东西:

[2,3] in [1,2,3,4]      #evaluates True
[1,5,4] in [5,1,5,4]    #evaluates True
[1,2] in [4,3,2,1]      #evaluates False

列表中的订单很重要。

2 个答案:

答案 0 :(得分:3)

def check_ordered_sublist_in_list(sub_list, main_list):
    sub_list = np.array(sub_list)
    main_list = np.array(main_list)
    return any(all(main_list[n:(n + len(sub_list))] == sub_list) 
               for n in range(0, len(main_list) - len(sub_list) + 1))

>>> check_ordered_sublist_in_list([2, 3], [1, 2, 3, 4])
True

>>> check_ordered_sublist_in_list([1, 5, 4], [5, 1, 5, 4])
True

>>> check_ordered_sublist_in_list([1, 2], [4, 3, 2, 1])
False

这会将列表转换为numpy数组(以提高计算效率),然后使用切片检查切片中是否包含sub_list。任何成功都会返回True。

答案 1 :(得分:2)

你可以用这个:

def is_in(short, long):
    return any(short==long[i:i+len(short)] for i in range(len(long)-len(short)+1))

is_in([2,3], [1,2,3,4])   # True
is_in([1,5,4], [5,1,5,4]) # True
is_in([1,2], [4,3,2,1])   # False

如果你真的关心速度,这些表达式会快20-30%:

def segments(long, length):
    return [long[i:i+length] for i in range(len(long)-length+1)]

def is_in_seg(short, long):
    return short in segments(long, len(short))

is_in_seg([1,5,4], [5,1,5,4])      # true
[1,5,4] in segments([5,1,5,4], 3)  # true

这比快47%,但它使用元组而不是列表:

import itertools
def segments_zip(long, length):
    return itertools.izip(*[long[i:] for i in xrange(length)])

(2,3) in segments_zip((1,2,3,4), 2)    # True
(1,5,4) in segments_zip((5,1,5,4), 3)  # True
(1,2) in segments_zip((4,3,2,1), 2)    # False

额外的速度来自使用itertools.izip,它可以在找到匹配时停止生成段;使用xrange,避免创建整个范围列表;并使用元组,这通常比列表略快。但是如果你必须将列表转换为元组来使用它,那么微小的速度优势就会消失。