Python 什么';“的意思是什么;iter(lambda:object()>;object(),object())”;

Python 什么';“的意思是什么;iter(lambda:object()>;object(),object())”;,python,python-2.7,lambda,iterator,Python,Python 2.7,Lambda,Iterator,运行此迭代器时: iter(lambda : object() > object(), object()) 迭代器连续输出True和False 但是,这是什么意思?它是如何执行的?正如评论中已经指出的,这是一个实现细节,它只是“碰巧”给出了一个交替的序列,即真和假(但是,我们无法预测第一个是真还是假) 让我们从关于CPython 2.7的一些事实开始: 如果python-2.x中的一个对象没有实现\uuuu eq\uuu,并且与同一类型的另一个对象进行比较,那么它会比较内存地址 一些内

运行此迭代器时:

iter(lambda : object() > object(), object())
迭代器连续输出
True
False


但是,这是什么意思?它是如何执行的?

正如评论中已经指出的,这是一个实现细节,它只是“碰巧”给出了一个交替的序列,即
(但是,我们无法预测第一个是
还是

让我们从关于CPython 2.7的一些事实开始:

  • 如果python-2.x中的一个对象没有实现
    \uuuu eq\uuu
    ,并且与同一类型的另一个对象进行比较,那么它会比较内存地址
  • 一些内存地址以后进先出的方式重复使用
让我们看看您的迭代器,这次使用的是not lambda函数和
print
s作为内存地址:

def cmp_objects():
    a = object()
    b = object()
    print id(a)
    print id(b)
    print a > b

x = iter(cmp_objects, object())
next(x), next(x), next(x), next(x), next(x)
其中:

69637872
69638064
False
69638064
69637872
True
69637872
69638064
False
69638064
69637872
True
69637872
69638064
False
因此
a
变量以
69637872
的内存地址开始,而
b
69638064
开始。由于
b
的内存地址较大,因此返回
False
。在下一次调用中,内存地址被交换(记住LIFO),依此类推

由于哨兵的内存地址(iter的第二个参数)不同于
True
False
的内存地址,因此循环从不停止,并交替给出
True
False


但是,获得此类序列的更好方法是:

>>> import itertools
>>> it = itertools.cycle((True, False))
这也有一个可预测的初值。如果在
下一次调用之间创建
对象
s,它也不会中断:

>>> x = iter(lambda : object() > object(), object())
>>> next(x)
True
>>> object()
<object at 0x4269610>
>>> next(x)
True
x=iter(lambda:object()>object(),object()) >>>下一(x) 真的 >>>对象() >>>下一(x) 真的

这个例子可能给出不同的结果,这样的结果是完全随机的

创建一个无限迭代器,在
True
False
之间进行选择,这似乎是一种故意愚蠢的方法。它也只适用于Python 2,即使在那里,它也依赖于一个实现细节。@juanpa.arrivillaga我想知道为什么会发生这种情况。想写个答案吗?你不明白什么?你看过文件了吗?它使用所有内置函数。。。是最后的暗示,一些不明显的东西。事实上,所有这些在Python3中都发生了变化,因为其行为并不理想。不支持比较的类型之间的比较应该出错,没有一些作为实现细节的任意默认顺序…。@juanpa.arrivillaga为什么它在
True
False
之间交替,为什么它认为
object()
s是可排序的…@cᴏʟᴅsᴘᴇᴇᴅ 两个参数
iter
一直调用作为第一个参数传递的可调用对象,直到遇到第二个参数sentinel值。嗯,这个哨兵永远不会遇到,因为可调用函数返回一个
bool
,而
bool
永远不等于
对象()。本质上,由于
object()
s是按其
id()
排序的,因此您会期望
True
False
的随机序列,至少这是我们所能保证的。但是Python重用最近被垃圾收集的对象的内存地址。