对象可枚举但不可索引?

Object is enumerable but not indexable?

问题总结和问题

我正在尝试查看一个对象中的一些数据,这些数据可以被枚举但不能被索引。我对 python 还是个新手,但我不明白这是怎么可能的。

既然能枚举,为什么不能像enumerate一样访问索引呢?如果没有,有没有办法单独访问这些项目?

实际例子

import tensorflow_datasets as tfds

train_validation_split = tfds.Split.TRAIN.subsplit([6, 4])

(train_data, validation_data), test_data = tfds.load(
    name="imdb_reviews", 
    split=(train_validation_split, tfds.Split.TEST),
    as_supervised=True)

取数据集的 select 个子集

foo = train_data.take(5)

可以 使用枚举遍历 foo:

[In] for i, x in enumerate(foo):
    print(i)

生成预期输出:

0
1
2
3
4

但是,当我尝试对其进行索引时 foo[0] 我得到了这个错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-2acbea6d9862> in <module>
----> 1 foo[0]

TypeError: 'TakeDataset' object does not support indexing

Python 只有在 class 有方法的情况下才允许这些事情:

任何class都可以定义一个而不定义另一个。 __getattr__ 如果效率低下,通常不定义。


1 __next____iter__ 返回的 class 所必需的。

在Python中,自定义classes的实例可以通过特殊的(或"dunder")__iter__方法实现枚举。也许这个 class 实现了 __iter__ 但没有实现 __getitem__.

Dunder 概述:https://dbader.org/blog/python-dunder-methods
__iter__ 方法的规范:https://docs.python.org/3/library/stdtypes.html#typeiter

这是 foo 可迭代的结果,但没有 __getitem__ 函数。您可以使用 itertools.isslice 来获取可迭代对象的第 n 个元素,例如

import itertools

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(itertools.islice(iterable, n, None), default)