O objeto é enumerável, mas não indexável?


10

Resumo e pergunta do problema

Eu estou tentando olhar para alguns dos dados dentro de um objeto que pode ser enumerado, mas não indexado. Ainda sou novato em python, mas não entendo como isso é possível.

Se você pode enumerá-lo, por que não pode acessar o índice da mesma maneira que enumera? E se não, existe uma maneira de acessar os itens individualmente?

O exemplo real

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)

Pegue um subconjunto selecionado do conjunto de dados

foo = train_data.take(5)

Eu posso iterar foocom enumerar:

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

que gera a saída esperada:

0
1
2
3
4

Mas então, quando tento indexar, foo[0]recebo este erro:

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

TypeError: 'TakeDataset' object does not support indexing

11
Porque enumerar não acessa um índice. Não existe o conceito de "enumerable" em python, é apenas iterable
juanpa.arrivillaga

Respostas:


6

O Python só permite essas coisas se a classe tiver métodos para eles:

Qualquer classe pode definir uma sem definir a outra. __getattr__geralmente não está definido se seria ineficiente.


1 1 __next__ é obrigatório na classe retornada por __iter__.


1

Isso é resultado de fooser iterável, mas não ter uma __getitem__função. Você pode usar itertools.isslicepara obter o enésimo elemento de um iterável como esse

import itertools

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.