こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Python: TypeError

Pythonでテキストファイルから数字を読み込む時に、スペースで区切られたデータをパラメータセットとして配列の中に格納したいのですが、その際にチェック事項があってFor LoopにTryを挟んでいます。この状態でどうしても下記のエラーが出るのですが、どのようにすれば良いのでしょうか?
宜しくお願い致します。


TypeError: argument 2 to map() must support iteration


---

def ReadOutput1():
f = open('C:/Users/.../output1.txt','rb')
output = []
for line in f:
ls = line.split(' ')
for i in range(4, 8)):
try:
modelParams[i-4] = map(add, float(ls[i]))
except ValueError:
(...)
return output

投稿日時 - 2014-12-04 10:39:49

QNo.8846723

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは

mapの第二引数にイテレータ型を要するということなので、lsの必要な部分[4:8]を数値化したリスト(ls_f)を作成して、それをmapの第二引数に与えてあげれば良いのではないでしょか?

def add(x):
return(x + 1.0)

line = "0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0e-12 8.0 9.0"
ls = line.split()
ls_f = list(map(float, ls[4:8])) # lsの必要な部分のみ数値化
print(list(ls_f)) # => [4.0, 5.0, 6.0, 7e-12]

modelParams = list(map(add, ls_f))
print(modelParams) # => [5.0, 6.0, 7.0, 1.000000000007]


※私の環境python3.4.2ではmapがリストを返さなかったので明示してリストにしています。
※よくわかりませんが、私の環境では、指数表示の数値文字をfloatに与えてもエラーになりませんでした、
 指数表示数値を別処理する必要があるのであれば、その関数をfloatの代わりに作成する必要があると思います。

投稿日時 - 2014-12-06 05:38:56

補足

私の使っているPython2.7では「テキストファイルからの読み込み」はエラーになります。現在2の方で慣れているので慣れているので、他に色々と不便を感じたら乗り換えたいと思います。
別処理は既に用意しています。最初のコードを書く段階でそこまで書くのは焦点が分散するかなと思いまして。

投稿日時 - 2014-12-06 16:44:15

お礼

ありがとうございます。
おそらくmapの使い方が間違っていたようでした。

>map(float, ls[4:8])

の使い方を知らず、

>float(map(add, ls[i]))

という形でやっていて失敗していたようです。
上記方法で上手く実行できました。ありがとうございます。

投稿日時 - 2014-12-06 16:38:37

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

そうなると、単純に
modelParams[i-4] = add(float(ls[i]))
なだけで、わざわざmapを使う必要はありません。


> 科学数値表示(例1.2345e-12)になっているものを例外処理を行い

これは、どういう例外処理でしょうか?
・ 1.2345e-12は「(おそらく誤差からくる)非常に小さい数値」なので 0 として扱う
→ 0.0000000000012345 と書いても同じ数値ですが、どう扱いますか?
・ 12.3はそのまま使う
→ 1.23e+1 と書いても同じ数値ですが、どう扱いますか?

指数表現の文字列でも、floatで数値に変換できます。
http://docs.python.jp/2/library/functions.html#float
2.xのマニュアルでは「引数が文字列の場合、十進の数または浮動小数点数を含んでいなければなりません」とちょっと曖昧な表現ですが
http://docs.python.jp/3.3/library/functions.html#float
3.xでは、「浮動小数点数リテラルで表記」と明記されています。

全て単純にfloatで変換→数値で判断して例外処理
というのがスマートだと思います。



スライスを使うと、リストの一部分をまとめて変更することができます
modelParams[0:4]=(1,2,3,4)
# modelParams[0] =1, modelParams[1]=2 , ...

なので、forのところは
modelParams[0:4]=map(add,map(float,ls[4:8] ))
と書くこともできます。



mapの戻り値は、Python2からPython3になったときに、リストからイテレータへ変更されています。
http://docs.python.jp/3.3/whatsnew/3.0.html#views-and-iterators-instead-of-lists
> いくつかの良く使われているAPIはもはやリストを返しません:
> map() and filter() return iterators.

他にも、2→3で大きく変更されています。
今回のTypeErrorは、(メッセージが若干違うものの)2,3共通なので問題ありません。
ですが、「Python2用のスクリプトをPython3で使おうとしてうまく動かない(あるいは、その逆)」ということがよくあります。
質問の際には、使用しているPyhtonのバージョンを明記するようにしましょう。

投稿日時 - 2014-12-06 08:35:17

お礼

ご回答ありがとうございます。
仰るとおりmap(float,ls[4:8] )で正常に動作しました。

科学数値表記とは使わないのですね?英語ではScientific Numberですので、日本語で直訳でいけるかと思いましたが失礼致しました。スライスの場合はそれぞれに数値化の処理を適用させなければならないので、後者のみ試しました。

以後はバージョンも明記するよう心がけます。

投稿日時 - 2014-12-06 16:56:56

ANo.1

http://docs.python.jp/2/library/functions.html#map

mapは map(関数, イテレータ型)
とすると
[ 関数(イテレータの0番目),関数(イテレータの1番目),関数(イテレータの2番目), ...]
というリストを返す関数です。
http://docs.python.jp/2/library/stdtypes.html#typeiter

map(add, float(ls[i]))
だと、floatは実数を返す関数であり、実数はイテレータ型ではありません。
よってエラーになります

TypeError: argument 2 to map() must support iteration
型のエラー: map()の 引数2 はイテレーションに対応していなければならない

と、エラーメッセージに書いてある通りです。


modelParams[i-4] = map(add, float(ls[i]))

は何がやりたいのでしょうか?

mapはリストを返します。
 modelParams[i-4] に入れたいのは、リストですか?( modelParams[i-4] = [1,2] みたいに )
 別の数値かなにかですか?( modelParams[i-4] = 3.5 みたいに )

投稿日時 - 2014-12-04 22:57:39

補足

ご回答ありがとうございます。そういうことでしたか。

ここでやりたかったのは、一度計算処理してoutput1.txtに出力したデータを再度読み込む際に、5番目のデータからある個数だけをmodelParamsに収納したかったのです。その際、科学数値表示(例1.2345e-12)になっているものを例外処理を行い、それ以外は単純にfloatで数値として認識させる作業を行っております。

txtにしなければ数値として通常認識するのですが(csvなどでも数値になりますが、ファイルを開いた時に、データセットで[]で括られたもの(scipy.optimize.minimizeでの戻り値など)にカンマを打てなかったり、スペース区切りにすると'['や']'にもそれぞれセル一つ分使ったりなので)、txtを使う方法で考えています。

少々複雑になりましたが、要は2段落目に示した通りで、3段落目は補足です。


>modelParams[i-4] に入れたいのは、リストですか?

ということで、この問いには数値になります。例:modelParams=[3 1 4 1 5 ...]


宜しくお願い致します。

投稿日時 - 2014-12-05 00:05:45

あなたにオススメの質問