gpt4 book ai didi

python - 如何检测两个Python迭代器产生相同的项目?

转载 作者:行者123 更新时间:2023-11-30 23:20:51 25 4
gpt4 key购买 nike

是否有一种简洁且节省内存的方法来确定两个迭代器 lines1lines2 是否产生相同的项目?

例如,这些迭代器可以是从文件对象检索的行:

with io.open(`some.txt`, 'r', encoding='...') as lines1:
with io.open(`other.txt`, 'r', encoding='...') as lines2:
lines_are_equal = ...

直觉上人们可以预料到

lines_are_equal = lines1 == lines2  # DOES NOT WORK

将给出所需的结果。然而,这将始终是False,因为它只比较迭代器的地址而不是产生的项目。

如果内存不是问题,可以将迭代器转换为列表并比较它们:

lines_are_equal = list(lines1) == list(lines2)  # works but uses a lot of memory

我已经检查了 itertools,希望找到类似的东西

lines_are_equal = itertools.equal(lines1, lines2)  # DOES NOT WORK

但是好像没有这样的功能。

到目前为止,我能想到的最好的方法是使用 itertools.zip_longest() 循环两个迭代器(Python 2:izip_longest()):

lines_are_equal = True
for line1, line2 in itertools.zip_longest(lines1, lines2):
if line1 != line2:
lines_are_equal = False
break

这确实给出了所需的结果,并且内存效率高,但感觉笨拙且不符合Python风格。

有更好的方法吗?

解决方案:应用评论中的集体智慧并回答这是一个单行辅助函数,即使两个迭代器相同或可以有尾随 None值:

def iter_equal(items1, items2):
'''`True` if iterators `items1` and `items2` contain equal items.'''
return (items1 is items2) or \
all(a == b for a, b in itertools.zip_longest(items1, items2, fillvalue=object()))

您仍然必须确保迭代器不会相互产生副作用。

最佳答案

使用 all 怎么样?使用生成器表达式:

lines_are_equal = all(a == b for a, b in itertools.zip_longest(lines1, lines2))

UPDATE 如果 iterable 可以生成尾随 None,则最好按照 user2357112 的评论指定 fillvalue=object() 。 (默认情况下,None 用于填充值)

lines_are_equal = all(a == b for a, b in
itertools.zip_longest(lines1, lines2, fillvalue=object()))

如果您的目的是比较两个文件,而不是任何可迭代文件,则可以使用 filecmp.cmp相反:

files_are_equal = filecmp.cmp(filename1, filename2)

关于python - 如何检测两个Python迭代器产生相同的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25216504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com