pythonでuniq

めちゃめちゃ(はてな記法忘れるほど)間が空いた上にとても昔の話で恐縮ですが。

配列操作の比較表: Ruby, Python, JavaScript, Perl, C++ - bkブログ

a[:] = []とかはちょっと変だけど、やっぱりPythonてシンプルだなあと思って見ていたのですが、uniqが無いことに気がつきました。

2.4以降ならsetでいいんじゃないかと思ったんですが、使い方あってるかな。

>>> a = (1, 2, 4, 2, 4)
>>> list(set(a))
[1, 2, 4]


3/14 追記

2.3ならsets.Setを使えばよさそうですね。

from sets import Set
list(Set("abudakadabura"))
['a', 'b', 'd', 'k', 'r', 'u']

ループのelseの続き

(これがどんな時に便利か、を考えてあとで書く)
といいつつ、Pythonのドキュメントに書かれているのと比べて特別面白い例を思いつきませんでした。

break 文と continue 文と ループの else 節

それより少し悲しいことに気がつきました。別の言語(というかテンプレートエンジン)では、forelseやforeachelseというキーワードを「ループが一度も実行されなかった場合に実行する」という意味で使っているみたいです。

Smartyforeachelseだとか、

JavaScript Templatesのforelseがそうなっているみたいです。

ループのelseとtryのelse

Pythonはかなり*ふつう*の言語だなあという気がします。なので、「嫌い」という理由でPythonを使わない人はいたとしても、「わからない、難しい」という理由でPythonを使わない人は少ないのではないかと思います。

そんな*ふつう*の言語Pythonの中でも、ちょっと驚いた点といえば、ループにelseがあることと、tryにelseがあることです。他の言語にあるのかな。

ループのelse

ループのelseは、ループを正常に抜けた時にだけ実行します*1。正常に抜けた時というのは、ループの条件式が偽になって抜けた時なんかのことで、正常じゃないというのはbreakで抜けた時です。

>>> for i in range(3):
	print i
else:
	print "end."

	
0
1
2
end.
>>> for i in range(3):
	print i
	break
else:
	print "end."

	
0
>>> 

(これがどんな時に便利か、を考えてあとで書く)

*1:「正常に」というのは私が勝手に思ったことを書いているだけで、Python用語ではありません

関数の引数いろいろ

キーワード引数

>>> def f1(a, b):
	print a, b

	
>>> f1(1, 2)
1 2
>>> f1(b=1, a=2)
2 1
>>> 

可変長引数をタプルや辞書で受け取る

>>> def f2(a, *b, **c):
	print a, b, c

	
>>> f2(1, 2, 3, d=4, e=5)
1 (2, 3) {'e': 5, 'd': 4}
  • 先頭の引数 1 は a に格納されました。
  • 名前無しで渡された余分な引数 2 と 3 は、タプルとして *b に格納されました
  • 名前付きで渡された余分な引数 d=4 と e=5 は、辞書として **c に格納されました

ふーん。なるほど。名前付きの引数が名前無しの引数の前だとダメみたいです。

>>> f2(1, d=2, 3, 4, e=5)
SyntaxError: non-keyword arg after keyword arg

あと、辞書に入れるつもりが、うっかり仮引数の名前とかぶってしまうとダメですね。

>>> f2(1, 2, 3, a=4, e=5)

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in -toplevel-
    f2(1, 2, 3, a=4, e=5)
TypeError: f2() got multiple values for keyword argument 'a'

関数定義、基底クラスのメソッド

すっかりこの日記の存在すら忘れてました。久しぶりにPythonでプログラムを書こうと思ったら、激烈にパイソン力が低下しておりました。

  • とりあえず関数を定義しようと思ってsubだったかfunctionだったかと悩んでいたらdefだった(0点)
  • クラスAを継承したクラスBで、んでメソッドもオーバライドしてる時に、基底クラス側のメソッドを呼び出す時は A.method(self) なんですね。要するにJavaのsuperみたいなものはないということか

7/21追記:superありました。コメント覧参照。指摘してくださった方ありがとうございます。

モンティ・ホール問題

モンティ・ホール問題とは、

  • 3つの扉があって、それぞれの後ろには、1つは商品、残り2つは山羊がいます
  • 司会者はどのドアが商品かを知っています。プレイヤーは知りません
  • プレイヤーがまず3つのうちの1つを選びます
  • 次に司会者はかならずハズレ(山羊)のドアを選びます
  • 次にプレイヤーは、今選んでいるドアを選ぶか、残ったもう一つのドアに変更するかを選択することができます

プレイヤーは最初の選択のままがよいのか、あるいは残ったドアに変更するのが良いのか。という問題です。ソースコードは後ほど。

$ python monty_hall.py
swicher, total 3000, hit 2032
sticker, total 3000, hit 1030

swicherの圧勝です。