为什么用不同值初始化的范围在 Python 3 中相互比较相等?
当我在我的解释器中执行以下命令时:
>>> r1 = range(0)
>>> r2 = range(2, 2, 2)
>>> r1 == r2
True
结果是 True
。为什么会这样?为什么两个不同的 range
具有不同参数值的对象被视为相等?
原文由 root 发布,翻译遵循 CC BY-SA 4.0 许可协议
为什么用不同值初始化的范围在 Python 3 中相互比较相等?
当我在我的解释器中执行以下命令时:
>>> r1 = range(0)
>>> r2 = range(2, 2, 2)
>>> r1 == r2
True
结果是 True
。为什么会这样?为什么两个不同的 range
具有不同参数值的对象被视为相等?
原文由 root 发布,翻译遵循 CC BY-SA 4.0 许可协议
直接引用 文档(强调我的):
使用 == 和 != 测试范围对象是否相等将它们作为序列进行比较。也就是说, 如果两个范围对象表示相同的值序列,则它们被认为是相等的。 (请注意,比较相等的两个范围对象可能具有不同的开始、停止和步骤属性,例如 range(0) == range(2, 1, 3) 或 range(0, 3, 2) == range(0, 4, 2).)
如果您将 range
s 与“相同”列表进行比较,您将得到不平等,如 文档中所述:
不同类型的对象,除了不同的数字类型,永远不会比较相等。
例子:
>>> type(range(1))
<class 'range'>
>>> type([0])
<class 'list'>
>>> [0] == range(1)
False
>>> [0] == list(range(1))
True
请注意,这明确仅适用于 Python 3。在 Python 2 中,其中 range
仅返回一个列表, range(1) == [0]
评估为 True
原文由 Jasper 发布,翻译遵循 CC BY-SA 3.0 许可协议
4 回答4.4k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
1 回答3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
1 回答4.5k 阅读✓ 已解决
1 回答3.8k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
range
对象是特殊的:Python 会将
range
对象作为 Sequences 进行比较。这实质上意味着 比较不评估它们 如何 表示给定序列,而是评估它们表示 什么。start
,stop
和step
参数完全不同的事实在这里没有区别,因为 _它们在展开时都代表一个空列表_:比如第一个
range
对象:第二个
range
对象:_两者都代表一个空列表_,因为两个空列表比较相等(
True
)所以range
代表 它们的对象。结果,您可以拥有完全不同 的外观
range
对象;如果它们代表相同的序列,它们将 比较 相等:两者都表示具有单个元素的列表
[1]
所以这两个也比较相等。不,
range
对象 真的很 特别:但请注意,即使比较不评估它们 如何 表示序列, 也可以 仅 使用
start
,step
的值以及len
range
对象;这对比较速度有非常有趣的影响:范围比较超快:
另一方面,列表..
是的..
正如 @SuperBiasedMan 所 指出的,这仅适用于 Python 3 中的范围对象。Python 2
range()
是一个普通的 ol’ 函数,它返回一个列表,而2.x
xrange
对象没有 Python 3 中对象所具有的比较功能( 不仅是这些.. )range
对象。直接从 Python 3
range
对象的源代码中查看 @ajcr 的引用答案。那里记录了两个不同范围之间的比较实际上需要什么:简单快速的操作。 Therange_equals
function is utilized in the _range_richcompare
function_ forEQ
andNE
cases and assigned to the _tp_richcompare
slot对于PyRange_Type
类型_。我相信
range_equals
的实现非常可读(因为它很简单)添加到这里:我也在这里散布了一些自己的评论;查看 _@ajcr 对 Python 等效项的回答_。