質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1530閲覧

list()を外すと'enumerate' object is not subscriptableのエラーが出る

magi201903

総合スコア29

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

0クリップ

投稿2019/03/17 13:27

編集2019/03/17 14:03

前提・実現したいこと

pythonで深層学習の勉強をしています。書籍『PythonとKerasによるディープラーニング』で、単語のone-hotエンコーディングを行うコードを実際に動かしていて、疑問に感じたコードがありました。しかし自分なりに修正して実行すると、エラーメッセージが出ました。

発生している問題・エラーメッセージ

for j, word in list(enumerate(sample.split()))[:max_length]:
という1行があります。

list()のある必然性が分からず、list()を削除し、以下のように書き直しました。
for j, word in enumerate(sample.split())[:max_length]:

すると、以下のようなエラーメッセージが出ます。
TypeError: 'enumerate' object is not subscriptable

### 知りたいこと
1.エラーの意味は「添え字にアクセスできないオブジェクトです」ですか?
2.list()があるとエラーが出ないようになる理屈を教えてください
3.そもそも[:max_length]は不要な気がするのですが、なぜあるのでしょうか

該当のソースコード

python3.X

1import numpy as np 2 3# This is our initial data; one entry per "sample" 4# (in this toy example, a "sample" is just a sentence, but 5# it could be an entire document). 6samples = ['The cat sat on the mat.', 'The dog ate my homework.'] 7 8# First, build an index of all tokens in the data. 9token_index = {} 10for sample in samples: 11 # We simply tokenize the samples via the `split` method. 12 # in real life, we would also strip punctuation and special characters 13 # from the samples. 14 for word in sample.split(): 15 if word not in token_index: 16 # Assign a unique index to each unique word 17 token_index[word] = len(token_index) + 1 18 # Note that we don't attribute index 0 to anything. 19 20# Next, we vectorize our samples. 21# We will only consider the first `max_length` words in each sample. 22max_length = 10 23 24# This is where we store our results: 25results = np.zeros((len(samples), max_length, max(token_index.values()) + 1)) 26for i, sample in enumerate(samples): 27 for j, word in list(enumerate(sample.split()))[:max_length]: 28 index = token_index.get(word) 29 results[i, j, index] = 1.

試したこと

ちなみに、[:max_length]を削除して以下のように書き直すと、エラーは出ません。
for j, word in enumerate(sample.split()):
enumerateはタプルを返す。これが謎を解くカギになっている気がしますが、よくわかりません。

以下のコードに直すとエラーが出ませんでした。
for j, word in enumerate(sample.split()[:max_length]):

補足情報(FW/ツールのバージョンなど)

google Colaboratoryを使っています。
https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/6.1-one-hot-encoding-of-words-or-characters.ipynb
ここにコードが載っています。

ikedas👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

1.エラーの意味は「添え字にアクセスできないオブジェクトです」ですか?

その認識であっています。

2.list()があるとエラーが出ないようになる理屈を教えてください

添字でアクセスできるオブジェクトに変換したため。


組み込み関数 — Python 3.7.3rc1 ドキュメント

enumerate オブジェクトを返します。 iterable は、シーケンスか iterator か、あるいはイテレーションをサポートするその他のオブジェクトでなければなりません。 enumerate() によって返されたイテレータの next() メソッドは、 (デフォルトでは 0 となる start からの) カウントと、 iterable 上のイテレーションによって得られた値を含むタプルを返します。

enumerate() の返り値は enumerate オブジェクトであって、添字操作はサポートされていません。(subscribtableでない)

以下の例では、enumerate() の返り値 enum は [(0, 1), (1, 2), (2, 3), (3, 4)] のようなリストであると思って添字操作を行ったのだと思いますが、enum[:2] のように添字操作は行なえません。

enum = enumerate([1, 2, 3, 4])

enumerate オブジェクトは iterator であり、__next__() が呼ばれると、インスタンス化したときに渡した iterable なオブジェクトの要素を添え字付きで1つずつ返すようになっています。
添字操作をする場合は「list() でリストにする」など添字操作が行えるオブジェクトに変換する必要があります。

python

1from collections.abc import Iterable 2 3array = [1, 2, 3, 4] 4 5# (1) enumerate はクラス 6print(enumerate) # <class 'enumerate'> 7 8enum = enumerate(array) 9print(enum) # <enumerate object at 0x7f76684a2900> 10 11# (2) enumerate クラスは iterable (__iter__ または __getitem__ 関数が定義されている。) 12print(isinstance(enum, Iterable)) # True 13 14# (3) enumerate オブジェクトからリストを作成する。 15print(list(enum)) # [(0, 1), (1, 2), (2, 3), (3, 4)]

3.そもそも[:max_length]は不要な気がするのですが、なぜあるのでしょうか

コメントの We will only consider the first max_length words in each sample. とあるように文章は長さがまちまちなので、各要素が単語である文章を表すリストから最大で max_length 要素だけ取り出すということですね。

投稿2019/03/17 14:18

編集2019/03/18 02:42
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2019/03/17 22:00

>enumerate オブジェクトは iterable であり、__iter__() が呼ばれると、インスタンス化したときに渡した iterable なオブジェクトを添え字付きで1つずつ返すようになっています。 ここの説明は怪しいかもしれません。 正:enumerate オブジェクトは iterator であり、__next__() が呼ばれると、インスタンス化したときに渡した iterable なオブジェクトの要素を添え字付きで1つずつ返すようになっています。
tiitoi

2019/03/18 02:42

コメントありがとうございます。 ご指摘いただいた点を修正しました。
magi201903

2019/03/20 18:10 編集

tiitoiさま 大変丁寧な説明、ありがとうございました。完全に理解はできていないので、pythonを学びながら、書いていただいた解説を折に触れ、見返します。 今回の回答を読み、コードを書くとき、添字でアクセスできるオブジェクトか否かを意識する必要があることを学びました。 3の[:max_length]の必要性についても理解できました。1文だけ1000単語とかある場合も、一律10単語までしか操作対象にしない、とした方が何かと便利ですよね。
magi201903

2019/03/20 18:10

hayataka2049さま ご助言、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問