关注+星标,每天学习Python新技能
在 Python 中,如何检查两个可迭代对象是否相等?这篇文章就来聊聊这些细节,用通俗的方式帮你搞清楚:在 Python 里,“相等”到底意味着什么。
如果我们有两个列表,并且我们想知道这两个列表中的项目是否相同,我们可以使用相等运算符==:
>>> lines1 = ["Grains", "Kindred", "Zia"]>>> lines2 = ["Grains", "Kindred", "Zia"]>>> lines1 == lines2True同样的也适用于比较 Tuples:
>>> p = (3, 4, 8)>>> q = (3, 5, 7)>>> p == qFalse但是,如果我们想比较一个列表和一个元组呢?
我们不能对此使用简单的相等性检查:
>>> lines1 = ["Grains", "Kindred", "Zia"]>>> lines2 = ("Grains", "Kindred", "Zia")>>> lines1 == lines2False要将列表中的项与 Tuples 中的项进行比较,我们可以将列表转换为 Tuples 或将 Tuples 转换为 List,然后检查是否相等:
>>> lines1 = ["Grains", "Kindred", "Zia"]>>> lines2 = ("Grains", "Kindred", "Zia")>>> lines1 == list(lines2)True这种方法也适用于比较任何其他类型的 iterable。
例如,我们这里有两个对象:itertools.chain
>>> file1a = open("year1-first.txt")>>> file1b = open("year1-second.txt")>>> file2a = open("year2-first.txt")>>> file2b = open("year2-second.txt")>>> from itertools import chain>>> year1 = chain(file1a, file1b)>>> year2 = chain(file2a, file2b)这些对象是可迭代对象,但它们也是迭代器,相等运算符不能很好地与迭代器配合使用。
如果我们遍历这两个对象,我们会看到它们中包含相同的项目.
>>> year1 == year2False因此,我们可以在比较它们之前将它们中的每一个转换为一个列表:
>>> list(year1) == list(year2)True这样就可以正确对比。
在我们比较之前将两个可迭代对象转换为列表或元组,这样确实可以, 但是,如果我们比较两个非常大的可迭代对象,并且这些可迭代对象通常在它们不同的前几个元素上有所不同,那么这种类型的比较将花费更多的内存和更多的时间。
例如,也许我们正在比较两个文件,这两个文件通常要么完全相同,要么在前几行中不同。
我们可以一次性将整个文件全部读入内存,然后对它们中的每一个进行比较:
>>> with open("results1.csv") as file1, open("results2.csv") as file2: same = (file1.read() == file2.read())这种检查不匹配值、设置布尔值和打破循环的样式实际上是 Python 的 any 和 all 函数旨在处理的。因此,我们可以通过使用生成器表达式和内置函数来做同样的事情
>>> with open("results1.csv") as file1, open("results2.csv") as file2: same = all( line1 == line2 for line1, line2 in zip(file1, file2, strict=True) )无论哪种方式,我们都会逐行遍历每个文件,比较每一行以确保它们相等,然后在完成比较后丢弃前面的行,并在发现不相等的行后立即停止。
我们也可以用于检查是否接近相等。
例如,也许我们正在读取 2 个 CSV 文件并进行比较,但我们只关心每行的第一列是否与文件中匹配:
>>> import csv with open("results1.csv") as file1, open("results2.csv") as file2: reader1, reader2 = csv.reader(file1), csv.reader(file2) same = all( row1[0] == row2[0] for row1, row2 in zip(reader1, reader2, strict=True) )如果你不关心你正在比较的可迭代对象的类型,并且只关心它们是否具有相同的 Sequences 相同的项目,那么这种比较风格效果很好, 因此,如果我们想检查一个列表和一个元组(或任何可迭代对象)是否具有相同的项目,我们可以使用这种方法.
到目前为止,所有这些方法都假设两个可迭代对象的顺序很重要, 如果你需要比较两个可迭代对象,而忽略它们项目的顺序怎么办?
>>> members = ["Gregory", "Barry", "Pablo", "Emily", "Donghee"]>>> speakers = ["Barry", "Donghee", "Emily", "Gregory", "Pablo"]好吧,如果项目是字符串、数字或其他可哈希对象,那么你可以将两个可迭代对象放在集合中,并检查这些集合是否相等:
>>> set(members) == set(speakers)True如果你的可迭代对象可能会重复项目,并且重复次数很重要,那么你可以使用集合计数器collections.Counter:
>>> hand1 = ["AS", "AS", "KS", "KH", "QC"]>>> hand2 = ["AS", "KH", "AS", "QC", "KS"]>>> from collections import Counter>>> Counter(hand1) == Counter(hand2)True也可以使用sorted功能:
>>> sorted(hand1) == sorted(hand2)True但是排序的过程比向对象添加项目要慢,因此我更喜欢使用而不是排序.

▲点击关注-免费领取
推荐阅读
DBOS:让 Python 工作流持久化,轻松应对中断与重试
不想折腾 Celery?试试这个轻量级 Django 异步任务方案
Python 任务排队还能这么简单?一文带你了解 simpleppyq
你没看错!ChatGPT Sandbox 竟然还在用 3 年前的 Python 版本?
点击 阅读原文