gpt4 book ai didi

python迭代类似dict的对象

转载 作者:太空狗 更新时间:2023-10-30 00:48:15 25 4
gpt4 key购买 nike

 class Test(object):

def __init__(self, store):
assert isinstance(store, dict)
self.store = store

def __getitem__(self, key):
return self.store[key]

我试着遍历这门课。据说在this doc实现 __getitem__ 应该足以遍历我的测试类。事实上,当我尝试迭代它时,它并没有告诉我我不能,但是我遇到了一个KeyError:

In [10]: a = Test({1:1,2:2})

In [11]: for i in a: print i
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-11-8c9c9a8afa41> in <module>()
----> 1 for i in a: print i

<ipython-input-9-17212ae08f42> in __getitem__(self, key)
4 self.store = store
5 def __getitem__(self, key):
----> 6 return self.store[key]
7

KeyError: 0
  • 你知道这个 0 来自哪里吗?(背后发生了什么)

我知道我可以通过添加一个 __iter__ 函数来解决它:

def __iter__(self):
return dict.__iter__(self.store)
  • 这是解决这个问题的最佳方法吗?(我也可能继承自 dict 类)。

最佳答案

您在找到的文档中遗漏了一个关键措辞:

For sequence types, the accepted keys should be integers and slice objects. [...] [I]f of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised.

Note: for loops expect that an IndexError will be raised for illegal indexes to allow proper detection of the end of the sequence.

粗斜体强调是我的。如果您接受,而不是整数,您就没有序列。

Python 词汇表解释更多;查看definition of sequence :

An iterable which supports efficient element access using integer indices via the __getitem__() special method and defines a __len__() method that returns the length of the sequence. [...] Note that dict also supports __getitem__() and __len__(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers.

所以序列接受整数索引,而这正是 for 在迭代 * 时提供的。当给定一个要迭代的对象时,如果除了 __getitem__ 之外别无他法,则会构造一个从 0 开始并不断增加计数器直到 的特殊迭代器>IndexError 被提出。在纯 Python 中:

def getitem_iterator(obj):
getitem = type(obj).__getitem__ # special method, so on the type
index = 0
try:
while True:
yield getitem(obj, index)
index += 1
except IndexError:
# iteration complete
return

实际的实现是在 C 中,参见 PySeqIter_Type definition and functions .

实现__iter__ method反而;它在存在时使用。因为你包装了一个字典,你可以简单地返回那个字典的迭代器(使用 iter() function 而不是直接调用特殊方法):

def __iter__(self):
return iter(self.store)

* 从技术上讲,for 不提供此功能。 for 只使用 iter(obj) 并且当没有 __iter__ 方法时,那个调用 产生特殊的迭代器可用。

关于python迭代类似dict的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40630678/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com