Python iter(x)和x之间的区别是什么?
Python iter(x)和x之间的区别是什么?,python,Python,iter(x)和x.\uuu iter\uuuu()之间有什么区别 根据我的理解,它们都返回一个listiterator对象,但在下面的示例中,我注意到它们并不相等: x = [1, 2, 3] y = iter(x) z = x.__iter__() y == z False 关于迭代器对象,有什么我不理解的吗?基于这类事情,Iter对象不具有相等性 请参见iter(x)==iter(x)也返回False。这是因为iter函数(调用\uuuuuu iter\uuuuuuu)返回的iter对象
iter(x)
和x.\uuu iter\uuuu()
之间有什么区别
根据我的理解,它们都返回一个listiterator
对象,但在下面的示例中,我注意到它们并不相等:
x = [1, 2, 3]
y = iter(x)
z = x.__iter__()
y == z
False
关于迭代器对象,有什么我不理解的吗?基于这类事情,Iter对象不具有相等性 请参见
iter(x)==iter(x)
也返回False
。这是因为iter函数(调用\uuuuuu iter\uuuuuuu
)返回的iter对象不会过载\uuuuuuu eq\uuuu
,因此仅在两个对象相同时返回True
在没有重载的情况下,==
与的比较相同
另外,x.\uuuuu iter\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()是iter(x)。\uuuuuuuuuuuuuuuuuuuu class\uuuuuuuuuuuuuu。当您执行a=iter(x)
和b=iter(x)
时,有两个迭代器指向一个对象。由于迭代器没有将\uuuu eq\uuu()
定义为指向的对象的相等,而是将迭代器实例定义为相等,因此即使iter(x)==iter(x)
也将返回false
iter()基本上调用对象的\uuu iter\uuu()函数:
如果没有第二个参数,o必须是支持迭代协议的集合对象(方法\uu iter\uu),或者它必须支持序列协议
通过调用iter(x)
或x来生成迭代器没有区别。您正在创建2个listiterator
对象并对它们进行比较。比较它们,看它们是否是相同的迭代器对象,而不是它们生成的对象
>>> test = [1,2,3,4]
>>> iter(test)
<listiterator object at 0x7f85c7efa9d0>
>>> test.__iter__()
<listiterator object at 0x7f85c7efaa50>
您可以看到它们都引用同一个对象
>>> test = [1,2,3,4]
>>> iter_one = iter(test)
>>> iter_two = iter_one
>>> print iter_one == iter_two
True
>>> iter_one.next()
1
>>> iter_two.next()
2
您可以通过再次将差异迭代器转换回列表来检查它们是否产生相同的输出
>>> print list(iter(test)) == list(test.__iter__())
True
它们并不总是完全相同的。从-
iter(o[哨兵])
返回一个迭代器对象。根据第二个参数的存在,第一个参数的解释非常不同。如果没有第二个参数,o必须是支持迭代协议的集合对象(\uuuuu iter\uuuuu()
方法),或者它必须支持序列协议(具有从0开始的整数参数的\uuuuuu getitem\uuuuuu()
方法)
但是对于列表的情况,它们是相似的,就像内部调用\uu iter\uuu()
一样。但它们都返回不同的迭代器对象,您可以分别迭代这两个对象的返回值,因此它们不相等
演示迭代器的一般情况的示例-
In [13]: class CA:
....: def __iter__(self):
....: print('Inside __iter__')
....: return iter([1,2,3,4])
....:
In [14]: c = CA()
In [15]: iter(c)
Inside __iter__
Out[15]: <list_iterator at 0x3a13d68>
In [16]: c.__iter__()
Inside __iter__
Out[16]: <list_iterator at 0x3a13908> #see that even the ids are different for the list_iterator objects.
In [17]: class BA:
....: def __getitem__(self,i):
....: print('Inside __getitem__')
....: return i+5
....:
In [18]: b = BA()
In [19]: iter(b)
Out[19]: <iterator at 0x3a351d0>
In [20]: x = iter(b)
In [21]: next(x)
Inside __getitem__
Out[21]: 5
In [23]: next(x)
Inside __getitem__
Out[23]: 6
正如您在上面所看到的,尽管i
已经精疲力竭,j
仍然处于起始位置,因此您可以看到两者都是完全不同的对象(具有不同的状态)。一个列表支持Python中的多个迭代器,因此调用iter()
每次都会返回一个新的迭代器对象,而它们没有自己的\uuuuueq\uuuuu
方法,因此最终Python会使用它们的ID对它们进行比较,这当然是不同的
>>> type(iter([])).__eq__
<method-wrapper '__eq__' of type object at 0x100646ea0>
>>> object.__eq__
<method-wrapper '__eq__' of type object at 0x100650830>
对于不同的迭代器,也可以获得True
,但前提是您返回的迭代器类型在比较时比较相等
有了这句话,千万不要调用iter(obj)
像obj.\uuuu iter\uuuu()
,因为在这种情况下,它不会在类上查找\uuuuuu iter\uuuuuu
,而是会首先在实例上查找\uuuu iter\uuuuuu
:
class A(object):
def __init__(self):
self.__iter__ = lambda: iter(())
def __iter__(self):
return iter([])
a = A()
print a.__iter__()
print iter(a)
# output
<tupleiterator object at 0x10842b250>
<listiterator object at 0x10842b2d0>
A类(对象):
定义初始化(自):
self.\uuuu iter=lambda:iter(())
定义(自我):
返回iter([]))
a=a()
打印a.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
印刷iter(a)
#输出
iter(x)==iter(x)
也将返回False
。您将获得两个独立的迭代器对象(即,您可以使用其中一个而不影响另一个)
y不是z
。考虑到确定迭代器是否产生相同输出的唯一方法是使用它们,从而使它们随后变得无用,您希望迭代器如何进行相等性比较?@Ness,它们都返回iter
对象<代码>x.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
class A(object):
def __iter__(self):
return self
def next(self):
pass
a = A()
y = iter(a)
z = a.__iter__()
print y == z # will print True
class A(object):
def __init__(self):
self.__iter__ = lambda: iter(())
def __iter__(self):
return iter([])
a = A()
print a.__iter__()
print iter(a)
# output
<tupleiterator object at 0x10842b250>
<listiterator object at 0x10842b2d0>