最近我遇到了宇宙逻辑的pywats,现在试着理解迭代器的乐趣部分:
>>> a = 2, 1, 3
>>> sorted(a) == sorted(a)
True
>>> reversed(a) == reversed(a)
False
好的,sorted(a)
返回一个list
,sorted(a) == sorted(a)
只是两个列表的比较。但是reversed(a)
返回reversed object
。那么为什么这些颠倒的物体是不同的呢?而id的比较让我更加困惑:
^{pr2}$
Tags:
id(reversed(a) == id(reversed(a)
返回True
,而reversed(a) == reversed(a)
返回{正如您在
customobject == customobject
时看到的,动态创建的对象直到比较发生后才被销毁,这是因为比较需要该对象。在但是在
id(co) == id(co)
的情况下,创建的自定义对象被传递给id()
函数,然后只需要id
函数的结果进行比较,因此创建的对象没有剩余的引用,因此该对象是垃圾回收的,然后,当Python解释器为==
操作的右侧重新创建一个新对象时,它会重用先前释放的空间。因此,两者的id
是一样的。在上面的行为是CPython的一个实现细节(在Python的其他实现中可能/可能没有不同)。而且你不应该依赖
^{pr2}$ids
的相等性。例如,在下面的情况下,它给出了错误的结果-原因还是如上所述(在为
reversed(b)
创建反向对象之前,对为reversed(a)
创建的reversed
对象进行垃圾回收)。在如果列表很大,我认为比较两个迭代器的相等性的最有效的方法是使用^{} 内置函数和用于python3.x的^{} 函数(对于python2.x使用^{} )。在
python3.x的示例-
Python 2.x的示例-
^{4}$这是因为遇到了第一个False值处的
all()
短路,python3.x中的`zip()返回一个迭代器,该迭代器从两个不同的迭代器中生成相应的元素。这不需要在内存中创建单独的列表。在演示-
sorted
返回一个列表,而reversed
返回一个reversed
对象,是一个不同的对象。如果在比较之前将reversed
的结果强制转换为一个列表,则它们将相等。在reversed
返回不实现特定__eq__
运算符的iterable,因此使用identity进行比较。在关于
id(reversed(a)) == id(reversed(a))
的混淆是因为在对第一个id(...)
调用求值后,可以释放iterable(没有引用它),并且第二个iterable可能在第二个id(...)
调用完成时重新分配到同一个内存地址。不过,这只是一个巧合。在试试看
将}进行比较,就会发现它们是不同的数字(因为在本例中,iterable对象不能被释放,因为它们被
id(ra1)
与{ra1
/ra2
变量引用)。在相关问题 更多 >
编程相关推荐