TypeError: 'int' object is not iterable
プログラミングと暇つぶし Python リストを見ていたら、「pythonにてstrの数字とintの数字を取り込んで全部int化されたリストを作りたい。けど、エラーがでてうまくいかない」って書いてあるところでなんか引っかかった。ブログで言及されているTypeError: 'int' object is not iterableは今まで見たことがないエラー。リスト関数list()ってよくよく考えるとイテレーターなものしか飲み込まないんですね。知らんかった。
で、こういう時ってmapなのかなぁっと思って書いた。*1
>>> [1, 2]+list(map(lambda x:int(x),list("34"))) [1, 2, 3, 4]
うーん、可読性悪いな。
- 補足
どういったものがイテレータで、どういったものが違うのか具体例を三つほど挙げます。数字やクラスはどうもダメみたいです。文字はイテレータですね。クラスについては、別途、イテレータとしての定義が可能です。
>>> list("a") ['a'] >>> list(1) Traceback (most recent call last): File "<pyshell#22>", line 1, in <module> list(1) TypeError: 'int' object is not iterable >>> class _: pass >>> list(_) Traceback (most recent call last): File "<pyshell#26>", line 1, in <module> list(_) TypeError: 'type' object is not iterable
- おまけ
やっぱ内包表記がシンプルですよね。
>>> [1,2]+[int(x) for x in "34"] [1, 2, 3, 4]
*1:python3のmapはlistを返すことはありません。変換しましょう
java to python
- Cがエラーを吐いたとき
僕が研究で使用しているシミュレーションのプログラムはCで記述されている。このプログラムでは、グローバル変数をマクロ(#define)で記述しています。こうしておいてパラメータの部分だけヘッダーファイルにまとめてから、pythonで
1.ヘッダーファイルのマクロを書き換える
2.コンパイル&実行
ってなことをやっているんですが、たまにエラーを吐くことがあるんですね。書き換え実行のスパンが短すぎるのだろうなと考えてsleepコマンドをかませるというのもやってみたのですが、効果はまちまち。コンパイルエラーしたら、マクロを書き換える前のパラメータでファイルが実行されているため、同じデータが記述されてしまいます。
- javaのコードを久しぶりに拝見
上記のような「データの中にまれに、同じ情報(ゴミ)が入ってる。除くコードを書いてみよう」ってことで、まずは、隣の要素と比較して出力するようなものを自分で書かずに適当にググる。ググったらyahoo!知恵袋で紹介されていた。なんだあるじゃないかってことで、javaのコードを見て、pythonに書き直してみました。
import java.util.ArrayList; import java.util.List; public class Duplicate { public static void main(String[] args) { String[] ss = {"b", "b", "a", "a", "c", "c"}; List<String> ls = new ArrayList<String>(); for (int i = 0; i < ss.length; i++) ls.add(ss[i]); String prev = ls.iterator().next(); List<String> ret = new ArrayList<String>(); ret.add(prev); for (String e: ls) { if (!prev.equals(e)) ret.add(e); prev = e; } System.out.println(ret); } }
長いですね。てか、ls.iterator().next()とかif (!prev.equals(e))の辺りはjavaってこういうメソッド用意されてるんだなと。以下、書き直したpythonのコードです。
ls = ["b", "b", "a", "a", "c", "c"] prev = next(iter(ls)) ret = [prev] for e in ls: if prev != e: ret.append(e) prev = e print(ret)
いや、まてよ。next(iter(ls))の下りってls[0]でよくね?っと思って書き直した。
ls = ["b", "b", "a", "a", "c", "c"] prev = ls[0] ret = [prev] for e in ls: if prev != e: ret.append(e) prev = e print(ret)
厳つかったjavaのコードだったが、大したことしてないな、これ。
hyクイックスタート
いつものようにTwitterでスルスルと時間を浪費していると、reddit.comだったかの海外の記事が回ってきまして、Hyというpythonのライブラリが使えるlispの存在を知り、ちょっと気になってクイックスタートから読んでました。以下、つたない導入手続き。
- HYをソッコーで手に入れる手順
Karen Rustadさん、Cuddlesをありがとう
Quickstart — hy 0.10.1 documentation
0.pythonをインストールする。(pathも通そう)
Welcome to Python.org
環境変数PATHの設定 - 環境設定と動作確認 - Pythonインストールと環境設定
1.pipを入れる。(場合によってはpythonにはじめから入ってるよ)
pipの使い方 (2014/1バージョン) — そこはかとなく書くよん。
2.お手元のterminalかcmdにpip install hy と入力(殆どの人はこれだけで使える)
3.インストールが終わったらhyと入力してREPL発動。
4.以下の例を打ち込んでみよう
=> (print "Hy!") Hy! => (defn salutationsnm [name] (print (+ "Hy " name "!"))) => (salutationsnm "YourName") Hy YourName!
5.Ctrlとdを押せば終了するよ
6.オーマイゴッド!すごいや、hyのプログラムが書いてみたいなぁ…
7.選ばれしエディタ(sublimetextでもメモ帳でもいいゾ)を開いて以下を書き込もう。
(print "I was going to code in python syntax, but then I got hy.")
8.furuegoe.hyで保存しよう。
9.terminalかcmdにhy furuegoe.hyと打ち込もう。
10.過呼吸にならないように深呼吸しよう。
11.やがて、君はクッソ汚い笑みを浮かべながら姿を消してしまい、筆舌に尽くし難い行動をとるようになる。
hy/quickstart.rst at master · hylang/hy · GitHub
*1:初めに申しておきますが、懐メロ邦楽とは関係ありません
数学の予想
- コラッツ予想
世の中には未解決の問題が数多存在する。今回紹介するものは、僕のようなアマチュアにも触れやすい、問題はシンプルだが難しい問題、コラッツ予想と呼ばれるものである。
- どんな予想か
コラッツ予想についてくわしく知りたい人はwikipediaでも読んでもらいたい。
コラッツの問題 - Wikipedia
で、ここでも軽く触れると、
ある自然数を用意する。次の操作を繰り返す。
・2で割りきれる数は2で割る。
・2で割れないときは3倍して1足す。
これを繰り返すだけで、1に必ずたどり着く。
というルールである。学部の頃はこれを手でかなり計算して、印刷用紙をセロテープでつなぎ合わせ、樹形図を書きなぐって、樹形図の枝が分岐する数の特徴について色分けをして、どのような特徴があるのか調べていた。今思えば、なんて原始的なことをしていたんだろう。本気で予想を解こうと目の色を変えていたのだろうか。けど、すごく楽しくて、今でも樹形図はどこかに保管されているはずである。
久々にpythonで書こうものなら、いとも簡単に関数を書くことができる。(勿論、他の言語でも簡単)
def col(x): print(x) while x >1: if x % 2 == 0: x = int(x/2) else: x = 3 * x + 1 print(x)
是非、皆さんもこの数の不思議を体験してもらいたい。ニュルニュルと数字が出力されるが、最終的には必ず1が出力されて止まってしまう。
>>> col(19999999) 19999999 59999998 29999999 89999998 44999999 134999998 67499999 202499998 101249999 303749998 151874999 455624998 227812499 683437498 341718749 1025156248 512578124 256289062 128144531 384433594 192216797 576650392 288325196 144162598 72081299 216243898 108121949 324365848 162182924 81091462 40545731 121637194 60818597 182455792 91227896 45613948 22806974 11403487 34210462 17105231 51315694 25657847 76973542 38486771 115460314 57730157 173190472 86595236 43297618 21648809 64946428 32473214 16236607 48709822 24354911 73064734 36532367 109597102 54798551 164395654 82197827 246593482 123296741 369890224 184945112 92472556 46236278 23118139 69354418 34677209 104031628 52015814 26007907 78023722 39011861 117035584 58517792 29258896 14629448 7314724 3657362 1828681 5486044 2743022 1371511 4114534 2057267 6171802 3085901 9257704 4628852 2314426 1157213 3471640 1735820 867910 433955 1301866 650933 1952800 976400 488200 244100 122050 61025 183076 91538 45769 137308 68654 34327 102982 51491 154474 77237 231712 115856 57928 28964 14482 7241 21724 10862 5431 16294 8147 24442 12221 36664 18332 9166 4583 13750 6875 20626 10313 30940 15470 7735 23206 11603 34810 17405 52216 26108 13054 6527 19582 9791 29374 14687 44062 22031 66094 33047 99142 49571 148714 74357 223072 111536 55768 27884 13942 6971 20914 10457 31372 15686 7843 23530 11765 35296 17648 8824 4412 2206 1103 3310 1655 4966 2483 7450 3725 11176 5588 2794 1397 4192 2096 1048 524 262 131 394 197 592 296 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
まぁ、何がしたかったって、スゲー長いブログの記事にしたかったっていうね。
続・リスト内包表記
- Python文法詳解買っちゃった
Amazon.co.jp: Python文法詳解: 石本 敦夫: 本
python文法詳解発売されたので早速買ってみました。p.81の4.2.2のリスト内包の欄にて、次のような記述を見つけたのでメモ。こんなこともできたんですね。
>>> L = [(1,'a'),(2,'b'),(3,'c')] >>> [c*i for i,c in L] ['a', 'bb', 'ccc'] >>> L = [(1,2),(3,4,5),(6,7,8,9)] >>> [car*sum(cdr) for car,*cdr in L] [2, 27, 144]
car, cdrという変数名になっているのはLispっぽいですね。*を付けることで残りのシーケンスを指すポインタ(?)として機能しています。
ちょっとLispで書いてみましょう。schemeの教科書なら一番初めに載ってる例です。
#lang racket > (car '(1 2 3 4)) 1 > (cdr '(1 2 3 4)) '(2 3 4)
(最近はracketでschemeも勉強しています。racketもとい、scheme, Lispに興味がある人は、こちらのURLへどうぞ)
いつ通りの書き方も載せておきましょう。添字(そえじ)が見やすい人はこちらでどうぞ。
>>> L = [(1,'a'),(2,'b'),(3,'c')] >>> [t[0]*t[1] for t in L] ['a', 'bb', 'ccc'] >>> L = [(1,2),(3,4,5),(6,7,8,9)] >>> [t[0]*sum(t[1:]) for t in L] [2, 27, 144]
- 何か違いはあるの?
(car,cdr)型と添字型。この二つの表記は全く同じ結果を出力するのでしょうか?どうやら、少しだけ違いがあるようです。
>>> L = [(1,2),(3,4,5),(6,7,8,9)] >>> [t[0]*t[1:] for t in L] [(2,), (4, 5, 4, 5, 4, 5), (7, 8, 9, 7, 8, 9, 7, 8, 9, 7, 8, 9, 7, 8, 9, 7, 8, 9)] >>> [car*cdr for car,*cdr in L] [[2], [4, 5, 4, 5, 4, 5], [7, 8, 9, 7, 8, 9, 7, 8, 9, 7, 8, 9, 7, 8, 9, 7, 8, 9]]
今度は、本に載っていた例を勝手に書き換えた、というかsum()を抜いた例です。よく見ると、片方はtuple型ですが、もう片方はlist型です。(そもそも、掛け算とポインタが入り混じった内包表記はよろしくないかもしれませんが。)なぜこうなるのかというと、
>>> a,*b = (1,2,3) >>> a 1 >>> b [2, 3]
こうなってるんでした。つまり、タプル(tuple)はこの(car,cdr)型にした途端にリスト(list)へと形を変えていたんですね。
研究進捗どうですか
- 国際学会に行くことになったよっ
久々に日記を書くわけですが、自分は修士生というのもあって日々自分の研究を進めております。進捗はボチボチ順調な感じです。国際学会に出席することになったので、ポスター発表の準備やら、英語の勉強やらを始めないとなぁとか思いつつ、「Linuxの認定試験を受けろ(LPIC Lv.1)」との内定先からの御達しがあったので、それもそろそろやる日を決めようかなっとか考えてたりします。
- 何から手を付けようか
このブログをご覧になられた方々は、僕の専攻を全く知らない思うんですが、僕は現在、統計学とシミュレーションを道具に、単純なルールに基づいて動くAIの作成を行っております。最先端の画像処理やテキストマイニングで使われている、いわゆる”機械学習”ほど複雑なものではありません。
ところが、自分は鯖エンジニアになる予定なので、今の研究は直接関係なかったりします。そこで、「今行っている研究」と「企業に入るにあたっての勉強」をする必要があります。この二つの学習をどのような順番で学んでいくかを上手く考えて、自分の中でいい影響を及ぼし合ってほしいなと思っているわけです。
- とりあえず、python
色々とやりたいことは増えましたが、手つかずな状態になってます。気が付けば、手を実際に動かすような勉強をせずに仏教哲学とか、ウィトゲンシュタインの言語ゲームってなんだろとか、飯の種にならない夢想は尽きないわけです。こういう自己の内面を見つめるような哲学は、認知科学っぽい分野とも取れる内容なので読んでいて面白いです。皆さんも、是非、哲学探究を読んでみてはどうでしょうか。
- 犬が喋ったような、赤ん坊が立ったような感覚
僕には歳の離れた弟がいるんですが、その弟も現在大学生になりました。宇宙工学を専攻しているらしく、また、プログラミングのサークルに入っているようです。いずれ抜かされてしまう気がしてならない(笑)僕の心配をよそに、弟はどんどん成長を続けています。兄はまったりしているというのに!
最近、お盆に弟と会う機会があり、弟がraspberry piで遊んでいるというではありませんか!これはまずい。弟に先を越されてしまう。兄の威厳が~~てなわけで、折角pythonをかじってる兄としては、pythonを使ってraspberry pi b+でサーバーを作るとの無謀な計画も遂行中だったりします。LPICの勉強になるしな、やったぜ。
#まずはmicroSD買おう
Amazon.co.jp: Think Bayes ―プログラマのためのベイズ統計入門: Allen B. Downey, 黒川 利明: 本
Amazon.co.jp: Python文法詳解: 石本 敦夫: 本
新しいpython本も続々出てるようだ。みんな見てくれよな!
リスト内包表記と条件式
- 内包表記条件式は色々できる
リスト内包表記というのは便利で、for文と組み合わせて次のようなリストが作れます。
>>> a = [2*x for x in range(5)] >>> a [0, 2, 4, 6, 8]
条件式を加えても同様の機能が得られます。
>>> a = [x for x in range(5) if x%2 == 0] >>> a [0, 2, 4]
次のように書くとエラーになりますが、
>>> a = [x if x%2 == 0 for x in range(5)] SyntaxError: invalid syntax
でも、elseで落としどころを用意してあげると、
>>> a = [x if x%2 == 0 else 'N' for x in range(5)] >>> a [0, 'N', 2, 'N', 4]
通る。ふーん。けどこうなると、'N'抜くのがめんどいなぁ