Об'єкт перелічується, але не піддається індексації?


10

Резюме проблеми та питання

Я намагаюся розглянути деякі дані всередині об'єкта, які можна перерахувати, але не індексувати. Я все ще новачок пітона, але не розумію, як це можливо.

Якщо ви можете перерахувати, чому ви не можете отримати доступ до індексу таким же чином, як перелічити? А якщо ні, чи є спосіб отримати доступ до предметів індивідуально?

Фактичний приклад

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
Тому що перерахування не має доступу до індексу. У python не існує поняття "перелічуваного", це просто ітерабельно
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)

0

У Python екземпляри користувацьких класів можуть реалізовувати перерахування за допомогою спеціального (або "дандерного") __iter__методу. Можливо, цей клас реалізує__iter__ але ні __getitem__.

Огляд даних: https://dbader.org/blog/python-dunder-methods
Характеристики __iter__методу: https://docs.python.org/3/library/stdtypes.html#typeiter


1
Не "перерахування", а "ітерація"
juanpa.arrivillaga
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.