比较2个Python列表的顺序

时间:2016-05-05 23:20:39

标签: python string list

我正在寻找一些帮助,比较2个Python列表的顺序, list1 list2 ,以检测 list2 何时出现故障

  • list1 是静态的,包含字符串a,b,c,d,e,f,g,h,i,j。这是“正确的”订单。
  • list2 包含相同的字符串,但字符串的顺序和数量可能会发生变化。 (例如a,b,f,d,e,g,c,h,i,ja,b,c,d,e

我正在寻找一种有效的方法,通过将 list1 list1 进行比较来检测 list2 的时间。

例如,如果 list2 a,c,d,e,g,i应该返回true(因为字符串是有序的)

如果 list2 a,d,b,c,e,则应返回false(因为字符串d无序显示)

6 个答案:

答案 0 :(得分:7)

首先,让我们定义list1

>>> list1='a,b,c,d,e,f,g,h,i,j'.split(',')
>>> list1
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

虽然您的list1恰好按字母顺序排列,但我们会假设。此代码无论如何都适用。

现在,让我们创建一个无序的list2

>>> list2 = 'a,b,f,d,e,g,c,h,i,j'.split(',')
>>> list2
['a', 'b', 'f', 'd', 'e', 'g', 'c', 'h', 'i', 'j']

以下是测试list2是否出现故障的方法:

>>> list2 == sorted(list2, key=lambda c: list1.index(c))
False

False表示无序。

这是一个有序的例子:

>>> list2 = 'a,b,d,e'.split(',')
>>> list2 == sorted(list2, key=lambda c: list1.index(c))
True

True表示有序。

忽略list1中不在list2

中的元素

让我们考虑一个list2,其元素不在list1中:

>>> list2 = 'a,b,d,d,e,z'.split(',')

要忽略不需要的元素,让我们创建list2b

>>> list2b = [c for c in list2 if c in list1]

我们可以像以前一样进行测试:

>>> list2b == sorted(list2b, key=lambda c: list1.index(c))
True

替代方法不使用sorted

>>> list2b = ['a', 'b', 'd', 'd', 'e']
>>> indices = [list1.index(c) for c in list2b]
>>> all(c <= indices[i+1] for i, c in enumerate(indices[:-1]))
True

答案 1 :(得分:3)

为什么需要将其与list1进行比较,因为list1似乎按字母顺序排列?你不能做到以下几点吗?

def is_sorted(alist):
    return alist == sorted(alist)

print is_sorted(['a','c','d','e','g','i'])
# True

print is_sorted(['a','d','b','c','e'])
# False

答案 2 :(得分:1)

这是一个在预期的线性时间内运行的解决方案。如果list1始终为10个元素且list2不再存在,那么这一点并不重要,但如果列表较长,基于index的解决方案将会遇到极端减速。

首先,我们预处理list1,以便我们可以快速找到任何元素的索引。 (如果我们有多个list2,我们可以执行一次,然后使用预处理的输出来快速确定是否对多个list2进行了排序:

list1_indices = {item: i for i, item in enumerate(list1)}

然后,我们检查list2的每个元素在list1中的索引是否低于list2的下一个元素:

is_sorted = all(list1_indices[x] < list1_indices[y] for x, y in zip(list2, list2[1:]))

我们可以使用itertools.izipitertools.islice做得更好,以避免实现整个zip列表,如果我们检测到list2已经出来,就可以节省大量工作在清单的早期订单:

# On Python 3, we can just use zip. islice is still needed, though.
from itertools import izip, islice
is_sorted = all(list1_indices[x] < list1_indices[y]
                for x, y in izip(list2, islice(list2, 1, None)))

答案 3 :(得分:0)

is_sorted = not any(list1.index(list2[i]) > list1.index(list2[i+1]) for i in range(len(list2)-1))

如果iterable中的任何项为true,则函数any返回true。我将它与一个循环遍历list2的所有值的生成器表达式相结合,并确保它们按照list1的顺序排列。

答案 4 :(得分:0)

VKR

答案 5 :(得分:0)

让我们假设当你写作时,list1是字符串a,b,c,d,e,f,g,h,i,这意味着a可能是&#39; zebra&#39;而字符串b实际上可能是“大象”。所以订单可能不是按字母顺序排列的。此外,如果项目在list2中但不在list1中,则此方法将返回false。

good_list2 = ['a','c','d','e','g','i']

bad_list2 = ['a','d','b','c','e']

def verify(somelist):
    list1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    while len(list1) > 0:
        try:
            list1 = list1[:list1.index(somelist.pop())]
        except ValueError:
            return False
    return True