Pythonマップオブジェクトは添え字化できません


83

次のスクリプトでエラーが発生するのはなぜですか。

payIntList[i] = payIntList[i] + 1000
TypeError: 'map' object is not subscriptable

payList = []
numElements = 0

while True:
        payValue = raw_input("Enter the pay amount: ")
        numElements = numElements + 1
        payList.append(payValue)
        choice = raw_input("Do you wish to continue(y/n)?")
        if choice == 'n' or choice == 'N':
                         break

payIntList = map(int,payList)

for i in range(numElements):
         payIntList[i] = payIntList[i] + 1000
         print payIntList[i]

5
Python 3を使用していますか?
Felix Kling 2011

@ user567797-これは私にとっては問題なく動作します@Felix:彼はステートメントとしてprintを使用しているため、python 3を使用していません!
Pushpak Dagade 2011

2
whileループの下にあるものはすべて、読みやすさを失うことなくpayIntList = [int(x) + 1000 for x in payList]; print(*payIntList, sep='\n')(またはfor x in payIntList: print xPython 2.xではprint関数ではない)短縮できます(おそらく、さらに読みやすくなります)。

2
@Guanidene:彼はマップオブジェクトを持っているので、Python3を使用しています。しかし、彼はその上でPython 2コードを実行しようとしているため、エラーが発生します。
Lennart Regebro 2011年

3
「Python3でPython2コードを実行するとエラーが発生するのはなぜですか」という質問が欲しいのですが、これらすべてを重複としてマークできます。;)
Lennart Regebro 2011年

回答:


138

Python 3では、mapタイプの反復可能なオブジェクトを返しますが、map添字リストではなく、を書くことができますmap[i]。リストの結果を強制するには、

payIntList = list(map(int,payList))

ただし、多くの場合、インデックスを使用しないことで、コードをより適切に書き出すことができます。たとえば、リスト内包表記の場合

payIntList = [pi + 1000 for pi in payList]
for pi in payIntList:
    print(pi)

6
この答えは正しいですが、理想的には、このようなユースケースのためにマップをリストに変換しないでしょう。マップはすでに反復可能であり、リストと比較して反復処理が1桁速いように見えます。したがって、インデックスが必要ないだけでなく、リストもまったく必要ありません。payIntListはすでにマップであるため、よりクリーンなコードは次のようになりますfor i in payIntList: print(i + 1000)
RustyToms 2018

17

map()リストを返すのではなく、mapオブジェクトを返します。

list(map)もう一度リストにしたい場合は、電話する必要があります。

さらに良いことに、

from itertools import imap
payIntList = list(imap(int, payList))

中間オブジェクトを作成するために大量のメモリを消費することはありません。 intsん。作成時にです。

また、if choice.lower() == 'n':2回行う必要がないようにすることもできます。

Pythonはサポートしています+=:あなたができることpayIntList[i] += 1000、そしてnumElements += 1あなたが望むなら。

本当にトリッキーになりたい場合:

from itertools import count
for numElements in count(1):
    payList.append(raw_input("Enter the pay amount: "))
    if raw_input("Do you wish to continue(y/n)?").lower() == 'n':
         break

および/または

for payInt in payIntList:
    payInt += 1000
    print payInt

また、Pythonでは4つのスペースが標準のインデント量です。


1
それはpython3の場合ですが、ここでは、ステートメントとしてprintを使用しているため、python2.xを使用しているようです。
Pushpak Dagade 2011

コードスニペット、メモリ内のすべてのintをリストに格納します。イテレータを使用すると、特に複数の変換レイヤーでメモリを節約listできますが、イテレータを追加すると、その利点が失われます。

1
これを行うlist(map(...))と、が作成されmap、次にが作成されlist、次にが削除さmapれるため、しばらくの間、両方が同時にメモリに保存されます。あなたがそうするとき、list(imap(...))これはそうではありません。そのため、「中間オブジェクトでメモリを使用する」と言いました
agf 2011

では、Python 2を想定していますか?次にlist(map(...))ため、冗長である-として、ドキュメントの状態、「[の結果は、map]常にリストです」。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.