比较Python列表中的元素顺序

时间:2011-11-05 23:20:12

标签: python

我正在尝试编写一个函数,如果True中的元素以lst1中出现的顺序出现在lst2中,则会返回lst1,但不一定连续。

例如,

test([29, 5, 100], [20, 29, 30, 50, 5, 100])应该返回True

test([25, 65, 40], [40, 25, 30, 65, 1, 100])应该返回False

这是我到目前为止所做的:

def test(lst1, lst2):
    for i in range(len(lst1)-len(lst2)+1):
        if lst2 == lst1[i:i+len(lst2)]:
            return True 
    return False 

4 个答案:

答案 0 :(得分:5)

这是使用Triptych提供的index的方法的迭代版本。我认为这可能是最好的方法,因为index应该比任何手动索引或迭代更快:

def test(lst1, lst2):
    start = 0
    try:
        for item in lst1:
            start = lst2.index(item, start) + 1
    except ValueError:
        return False
    return True

它在Python中的表现要比递归版本好得多。它还在每次搜索后正确地将一个添加到起点,以便在第一个列表中存在重复时不会给出误报。

以下两种解决方案主要在lst2而不是lst1上进行迭代,但在其他方面与jedwards的版本相似。

第一个是直截了当的,并且使用索引,但只在您实际移动到lst1中的其他项目而不是lst2中的每个项目时进行索引:

def test(lst1, lst2):
    length, i, item = len(lst1), 0, lst1[0]
    for x in lst2:
        if x == item:
            i += 1
            if i == length:
                return True
            item = lst1[i]
    return False

第二个使用lst1next进行手动迭代而不是索引:

def test(lst1, lst2):
    it = iter(lst1)
    try:
        i = next(it)
        for x in lst2:
            if x == i:
                i = next(it)
    except StopIteration:
        return True
    return False

两者都可能略有改进,因为它们的索引编制较少,而且无需为range中的每个项目构建lst1

答案 1 :(得分:2)

递归地,没有破坏列表,没有新的子列表,早期失败

def find_all(needle, haystack, npos=0, hpos=0):
  if npos >= len(needle):
    return True
  try:
    return find_all(needle, haystack, npos+1, haystack.index(needle[npos], hpos)+1) 
  except ValueError:
    return False


print find_all([1,3,5], [1,2,3,4,5,6,7]) # True
print find_all([1,5,3], [1,2,3,4,5,6,7]) # False

答案 2 :(得分:1)

这会扫描列表,这是一种不同的方法:

def test(lst1, lst2):
    p2 = 0
    length = len(lst2)
    for e1 in lst1:
        for p in range(p2, length):
            if e1 == lst2[p]:
                p2 = p
                break
        else:
            return False    
    return True

对于lst1中的每个元素,它搜索列表2的子集(在p2和结束之间)。如果找到,则会通过更新p2来限制搜索后的范围。如果未找到,则返回False。如果找到True中的每个元素,则会返回lst1

答案 3 :(得分:0)

def test(lst1, lst2):
    for x in lst2:
        if x == lst1[0]:
            del lst1[0]
    return lst1 == []

应该工作。