Mah*_*r I 8 python dictionary iterator python-3.x
我已经实现了一个 python 类来生成数据,如下所示:
class Array:
def __init__(self):
self.arr = [1,2,3,4,5,6,7,8]
def __getitem__(self,key):
return self.arr[key]
a = Array()
for i in a:
print(i, end = " ")
Run Code Online (Sandbox Code Playgroud)
它按预期运行,我得到了关注
1 2 3 4 5 6 7 8
Run Code Online (Sandbox Code Playgroud)
但是,我想对字典做同样的事情。为什么我不能像这样迭代字典?
class Dictionary:
def __init__(self):
self.dictionary = {'a' : 1, 'b' : 2, 'c': 3}
def __getitem__(self,key):
return self.dictionary[key]
d = Dictionary()
for key in d:
print(key, d[key], end=" ")
Run Code Online (Sandbox Code Playgroud)
我希望以下输出
a 1 b 2 c 3
Run Code Online (Sandbox Code Playgroud)
但是当我运行上面的代码时,出现以下错误:
Traceback (most recent call last):
File "<ipython-input-33-4547779db7ec>", line 8, in <module>
for key in d:
File "<ipython-input-33-4547779db7ec>", line 6, in __getitem__
return self.dictionary[key]
KeyError: 0
Run Code Online (Sandbox Code Playgroud)
我们可以遍历普通的字典是这样的:for key in d。这将遍历所有键,是否可以使用__getitem__()?
一个for循环可与迭代器,对象,可以传递给next。如果一个对象有一个__next__方法,它就是一个迭代器。
无论你的班呢,所以Python会先通过你的对象iter,以获得一个迭代器。iter尝试做的第一件事是调用对象的__iter__方法。
您的两个类都没有定义__iter__,因此iter接下来检查其对象是否定义了__getitem__。你的两个类都这样做,所以iter返回一个 type 的对象iterator,其__next__方法可以被想象成是这样的
def __next__(self):
try:
rv = self.thing.__getitem__(self.i)
except IndexError:
raise StopIteration
self.i += 1
return rv
Run Code Online (Sandbox Code Playgroud)
(迭代器持有对定义的事物的引用__getitem__,以及i在调用__next__.之间跟踪状态的值i被假定初始化为 0。)
对于Array,这是有效的,因为它具有整数索引。对于Dictionary,虽然0不是关键和,而不是提高了IndexError,你会得到一个KeyError与__next__方法并没有赶上。
(这是在文档中__getitem__提到的:
注意 for 循环期望为非法索引引发 IndexError 以允许正确检测序列的结尾。
)
要使您的Dictionary类可迭代,请定义__iter__
class Dictionary:
def __init__(self):
self.dictionary = {'a' : 1, 'b' : 2, 'c': 3}
def __getitem__(self,key):
return self.dictionary[key]
def __iter__(self):
return iter(self.dictionary)
Run Code Online (Sandbox Code Playgroud)
dict.__iter__返回一个 type 的值dict_keyiterator,它是产生dict的键的东西,您可以将其与 一起使用Dictionary.__getitem__。
将以下方法添加到您的Dictionary类就足以让它工作:
def __iter__(self):
return iter(self.dictionary)
Run Code Online (Sandbox Code Playgroud)
重要说明:创建序列或映射的自定义类时,您应该实现所有相关方法。否则,您的代码(例如,等)要么效率低下x in y,for x in y要么被破坏,就像您在Dictionary类中看到的那样。
有关更多详细信息,请参阅:https : //docs.python.org/3/reference/datamodel.html?emulating-container-types#emulating-container-types。
| 归档时间: |
|
| 查看次数: |
798 次 |
| 最近记录: |