web-dev-qa-db-ja.com

オブジェクトは列挙可能ですが、インデックス付けはできませんか?

問題の概要と質問

列挙することはできても、インデックスを作成できないオブジェクト内のデータを調べようとしています。私はまだ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)

I can列挙して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
10
Phillip Geltman

これは、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)
1
kopecs

Pythonでは、カスタムクラスのインスタンスは、特別な(または「dunder」)__iter__メソッドを介して列挙を実装できます。おそらく、このクラスは__iter__を実装しますが、__getitem__は実装しません。

Dunderの概要: https://dbader.org/blog/python-dunder-methods
__iter__メソッドの仕様: https://docs.python.org/3/library/stdtypes.html#typeiter

0
Exr0n