Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object is enumerable but not indexable?

Problem summary and question

I'm trying to look at some of the data inside an object that can be enumerated over but not indexed. I'm still newish to python, but I don't understand how this is possible.

If you can enumerate it, why can't you access the index through the same way enumerate does? And if not, is there a way to access the items individually?

The actual example

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)

Take a select subset of the dataset

foo = train_data.take(5)

I can iterate over foo with enumerate:

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

which generates the expected output:

0
1
2
3
4

But then, when I try to index into it foo[0] I get this error:

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

TypeError: 'TakeDataset' object does not support indexing
like image 840
Phillip Geltman Avatar asked Dec 30 '19 02:12

Phillip Geltman


2 Answers

This is a result of foo being iterable, but not having a __getitem__ function. You can use itertools.isslice to get the nth element of an iterable like so

import itertools

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(itertools.islice(iterable, n, None), default)
like image 100
kopecs Avatar answered Nov 15 '22 21:11

kopecs


Python only allows these things if the class has methods for them:

  • __getitem__ is required for the [] syntax.
  • __iter__ and __next__1 are required to iterate.

Any class can define one without defining the other. __getattr__ is usually not defined if it would be inefficient.


1__next__ is required on the class returned by __iter__.

like image 6
Anonymous Avatar answered Nov 15 '22 22:11

Anonymous