比较序列的优雅方法

2024-04-27 11:55:57 发布

您现在位置:Python中文网/ 问答频道 /正文

python是否提供了一种优雅的方法来检查不同类型序列的“相等性”?下面的代码可以工作,但是对于python代码来说,它们看起来相当难看和冗长:

def comp1(a, b):
    if len(a) != len(b):
        return False
    for i, v in enumerate(a):
        if v != b[i]:
            return False
    return True

由于创建了第三个序列,因此下面的代码稍短,但效率也较低:

def comp2(a, b):
    for l, r in map(None, a, b):
        if l != r:
            return False
    return True

把这些例子中的一个塞进一个列表理解中也不是我想要的。

编辑:理想情况下,我正在寻找一个解决方案,在比较期间不会创建另一个序列。


Tags: 方法代码infalsetrue类型forlen
3条回答

将两个序列转换为列表,并使用内置列表比较。它应该足够了,除非你的序列真的很大。

list(a) == list(b)

编辑:

schickb所做的测试表明,使用元组稍微快一些:

tuple(a) == tuple(b)

除了创建临时列表/元组所使用的额外内存外,当序列中的不等式出现在早期时,这些答案将丢失给大型序列的短路生成器解决方案

from itertools import starmap, izip
from operator import eq
all(starmap(eq, izip(x, y)))

或者更简洁

from itertools import imap
from operator import eq
all(imap(eq, x, y))

来自ipython的一些基准

x=range(1000)
y=range(1000); y[10]=0

timeit tuple(x) == tuple(y)
100000 loops, best of 3: 16.9 us per loop

timeit all(imap(eq, x, y))
100000 loops, best of 3: 2.86 us per loop

您可以使用以下命令确定任意两个iterable(字符串、元组、列表,甚至自定义序列)的相等性,而无需创建和存储重复的列表:

all(x == y for x, y in itertools.izip_longest(a, b))

请注意,如果两个iterable的长度不相同,则较短的iterable将用Nones填充。换句话说,它将认为[1, 2, None]等于(1, 2)

编辑:正如Kamil在评论中指出的,izip_longest仅在Python 2.6中可用。但是,the docs for the function还提供了一个替代实现,它应该一直工作到2.3。

编辑2:在几个不同的机器上进行测试后,在某些情况下,这看起来只比list(a) == list(b)快,而我无法隔离。大多数情况下,这需要大约7倍的时间。不过,我也发现tuple(a) == tuple(b)的速度至少是list版本的两倍。

相关问题 更多 >