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クイックスタート

  • hyを始めよう*1

いつものようにTwitterでスルスルと時間を浪費していると、reddit.comだったかの海外の記事が回ってきまして、Hyというpythonのライブラリが使えるlispの存在を知り、ちょっと気になってクイックスタートから読んでました。以下、つたない導入手続き。

  • HYをソッコーで手に入れる手順

f:id:kerorosho-tai:20141124020023p:plain
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へどうぞ)


The Racket Language

いつ通りの書き方も載せておきましょう。添字(そえじ)が見やすい人はこちらでどうぞ。

>>> 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の作成を行っております。最先端の画像処理やテキストマイニングで使われている、いわゆる”機械学習”ほど複雑なものではありません。
 ところが、自分は鯖エンジニアになる予定なので、今の研究は直接関係なかったりします。そこで、「今行っている研究」と「企業に入るにあたっての勉強」をする必要があります。この二つの学習をどのような順番で学んでいくかを上手く考えて、自分の中でいい影響を及ぼし合ってほしいなと思っているわけです。

 色々とやりたいことは増えましたが、手つかずな状態になってます。気が付けば、手を実際に動かすような勉強をせずに仏教哲学とか、ウィトゲンシュタイン言語ゲームってなんだろとか、飯の種にならない夢想は尽きないわけです。こういう自己の内面を見つめるような哲学は、認知科学っぽい分野とも取れる内容なので読んでいて面白いです。皆さんも、是非、哲学探究を読んでみてはどうでしょうか。
 

  • 犬が喋ったような、赤ん坊が立ったような感覚

 僕には歳の離れた弟がいるんですが、その弟も現在大学生になりました。宇宙工学を専攻しているらしく、また、プログラミングのサークルに入っているようです。いずれ抜かされてしまう気がしてならない(笑)僕の心配をよそに、弟はどんどん成長を続けています。兄はまったりしているというのに!
 最近、お盆に弟と会う機会があり、弟が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'抜くのがめんどいなぁ