Объект перечислим, но не индексируется?

10

Краткое изложение проблемы и вопрос

Я пытаюсь посмотреть на некоторые данные внутри объекта, которые можно перечислить, но не проиндексировать. Я все еще новичок в Python, но я не понимаю, как это возможно.

Если вы можете перечислить его, почему вы не можете получить доступ к индексу тем же способом, что и перечисление? И если нет, есть ли способ получить доступ к элементам индивидуально?

Фактический пример

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)

Возьмите выделенное подмножество набора данных

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
Филипп Гельтман
источник
1
Потому что перечисление не имеет доступа к индексу. В питоне нет понятия «перечислимое», оно просто повторяемое
juanpa.arrivillaga

Ответы:

6

Python допускает эти вещи только в том случае, если у класса есть методы для них:

Любой класс может определить один без определения другого. __getattr__обычно не определяется, если это будет неэффективно.


1 __next__ требуется для класса, возвращаемого __iter__.

анонимное
источник
1

Это результат того, 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)
kopecs
источник
0

В Python экземпляры пользовательских классов могут реализовывать перечисление с помощью специального (или более сложного) __iter__метода. Возможно, этот класс реализует, __iter__но нет __getitem__.

Обзор Dunder: https://dbader.org/blog/python-dunder-methods
Спецификации для __iter__метода: https://docs.python.org/3/library/stdtypes.html#typeiter

Exr0n
источник
1
Не «перечисление», а «итерация»
juanpa.arrivillaga