split()とsplit(" ")で出力が異なる件について
掲題の通り。
split()
とsplit(" ")
では、微妙に出力結果が違うことに注意。
>>> space1 = "a b"
>>> space2 = "a b"
>>> space3 = "a b"
>>> [i for i in space1.split()]
['a', 'b']
>>> [i for i in space1.split(" ")]
['a', 'b']
>>> [i for i in space2.split()]
['a', 'b']
>>> [i for i in space2.split(" ")]
['a', '', 'b']
>>> [i for i in space3.split()]
['a', 'b']
>>> [i for i in space3.split(" ")]
['a', '', '', 'b']
Pythonでの多次元配列の定義方法
Pythonで多次元配列の定義についてのメモ。
基本的にはリスト内包表記で次のように配列を作ります。
>>> arr2 = [[0 for i2 in range(4)] for i1 in range(3)]
にて作成可能。
例えば、要素数1が3、要素数2が4、要素数3が5の3次元配列arr3は、
>>> arr3 = [[[0 for i3 in range(5)] for i2 in range(4)] for i1 in range(3)]
にて作成可能。 arr3[i1][i2][i3]の値の操作は、
>>> arr3[1][2][3] = 1
>>> arr3
[[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]
と言った感じで扱える。
Python3におけるmap/filterの使い方
はじめに
map()/filter()の使いどころがよくわからないので、自分なりに調査をしてみた。
この2つの関数は、Python2系とPython3系では挙動が異なるので、まずはその話から。
まずは、具体的に実行内容を見てみたい。
python2系での実行結果
>>> print(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(map(lambda x: x*2, range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> print(filter(lambda x: x % 2, range(10)))
[1, 3, 5, 7, 9]
python3系での実行結果
>>> print(range(10))
range(0, 10)
>>> print(map(lambda x: x*2, range(10)))
<map object at 0xb7bdd74c>
>>> print(filter(lambda x: x % 2, range(10)))
<filter object at 0xb7bdd74c>
Python2系では,上に挙げたそれぞれの関数、メソッドはそれぞれリストを返している。
しかし,Python3系ではリストではなく、iterator objectを返すように挙動が変更された。
iteratorを返すことで、一度に全要素を計算せず、要素が必要とされる時に計算するようになり、使用するメモリ量を低く抑えているとのこと。
2系のように、iteratorをリスト化したい場合はiteratorをlist関数に渡してリストを生成すればよい。
>>> print(list(map(lambda x: x*2, range(10))))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> print(list(filter(lambda x: x % 2, range(10))))
[1, 3, 5, 7, 9]
set関数に渡せば、iteratorより集合も生成可能。
>>> print(set(map(lambda x: x*2, range(10))))
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
>>> print(set(filter(lambda x: x % 2, range(10))))
{1, 9, 3, 5, 7}
map()
map()とは、リストの要素に演算を適用してくれる関数。
map(func, iterable, ...)
第2引数以降のiterableを順にfuncに渡した結果をyieldで返す(generator)。
引数iteratbleは第1引数の関数の引数に順に渡される。
基本的な使い方としては、以下のように各要素の2乗されたリストを生成などがある。
>>> def square(x):
... return x * x
...
>>> map(square, range(1, 10))
<map at 0x7f474ad63e80>
>>> list(map(square, range(1, 10)))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
ラムダ式を用いれば、1行で同様の結果を得ることができる。
>>> map(lambda x: x*x, range(1, 10))
<map at 0x7f474ad67128>
>>> list(map(lambda x: x*x, range(1, 10)))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
内包記法を使えば、直接リストを生成することができる。
>>> [x*x for x in range(1, 10)]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
filter()
filter()とは、リストの要素を抽出してくれる関数。
filter(func, iterable)
iterableのオブジェクトを順にfuncに渡し、funcがTrueで返したオブジェクトをieldで返す(generator)。
>>> def is_mod(x):
... return x % 3 == 1
...
基本的な使い方としては、以下のように各要素の3で割ったときに1余る要素のリストを生成などがある。
>>> filter(is_mod, range(1 ,10))
<filter at 0x7f474ad77f28>
>>> list(filter(is_mod, range(1 ,10)))
[1, 4, 7]
ラムダ式を用いれば、1行で同様の結果を得ることができる。
>>> filter(lambda x:x % 3 == 1, range(1, 10))
<filter at 0x7f474ad7d400>
>>> list(filter(lambda x:x % 3 == 1, range(1, 10)))
[1, 4, 7]
内包記法を使えば、直接リストを生成することができる。
>>> [x for x in range(1 ,10) if x % 3 == 1]
[1, 4, 7]
filter() と map()の組み合わせ
リストの要素を抽出して演算を適用する。
例えば、3で割ったとき余りが1になる要素を取得して、取得した各要素を2倍するとする。
通常の通りにやろうとすると、以下の通りになる。
>>> result = []
>>> for x in range(1, 10):
... if x % 3 == 1:
... result += [x * 2]
... print(result)
...
[2, 8, 14]
filter()、map()を用いて書くと、以下のようになる。
>>> map(lambda x: x * 2, filter(lambda x: x % 3 == 1, range(1, 10)))
<map at 0x7f474ad772e8>
>>> list(map(lambda x: x * 2, filter(lambda x: x % 3 == 1, range(1, 10))))
[2, 8, 14]
内包記法を使ってのリスト生成は以下の通り。
>>> [x * 2 for x in range(1, 10) if x % 3 == 1]
[2, 8, 14]
最後に
今回のネタは以下のサイトを参考にしました。
- Python 3.0 Hacks 第8回 リスト処理と内包表記
- Python の map, filter, reduce とリスト内包表記
- 何気にPythonでつかっていた関数型プログラミング技法いろいろ
特に「何気にPythonでつかっていた関数型プログラミング技法いろいろ」の情報は2系ではよくまとまっていると思う。
reduce()についてもどっかのタイミングで調べておきたいなと思った。
Pythonでの日付の扱い
自分用に忘れないためのメモを残す。
基本パターン1
>>> import datetime
# 日付の格納
>>> day = datetime.date(2016, 2, 22)
# 1日進める
>>> print(day + datetime.timedelta(days=1))
2016-02-23
# 1日戻す
>>> print(day - datetime.timedelta(days=1))
2016-02-21
基本パターン2
>>> now = datetime.datetime.now()
>>> print(now)
2016-02-22 23:36:57.814567
# 1時間戻す
>>> print(now - datetime.timedelta(hours = 1))
2016-02-22 22:36:57.814567
# 1分戻す
>>> print(now - datetime.timedelta(minutes = 1))
2016-02-22 23:35:57.814567
# 1秒戻す
>>> print(now - datetime.timedelta(seconds = 1))
2016-02-22 23:36:56.814567
宿題
月単位での操作、年単位での操作をする方法がわからないので、追って調査する。
Python3で文字列リストの変換をmapでしようとしたらハマった件について
したいこと
文字列
a1 = ['0', '12.2','23']
を
[0.0, 12.2, 23.0]
と、リストの要素を文字列からfloatへ変換して出力させたい。
Python2.X系だと、以下で求めたいListが出力される。
>>> a1_str = map(float,a)
しかし、Python3.4.3で実行するとmapオブジェクトが返される。
よって、以下のようにリスト化すればよい…とはいかない。1回イテレートすると消えてしまう仕様のため、2回目にイテレートすると空になってしまう。
>>> a1_list = list(a1_str)
>>> print(a1_list)
[]
それを回避する方法として、内包表記を用いて一発でリスト化する方法を用いる。
>>> a1_list = [float(i) for i in a1]
もうちょい
では逆は?
リストの要素をintから文字列に変換したいとする。
>>> a2 = [1, 2, 3]
>>> [str(i) for i in a2]
['1', '2', '3']
ちょっとした応用
以下の文字列
a3 = '10 20 30'
から、以下のint型のリスト
[10, 20, 30]
を生成したい。
これは、
[int(i) for i in a3.split(' ')]
により生成可能。
IPython notebookのリモート接続に関する件について
はじめに
IPython notebookは便利っぽい。
なので、CentOSサーバにいれて、みんなでつつけるように出来たらもっと便利だろうと。
デフォルトだとリモート接続できるように設定せにゃあかんいうことで、その設定について備忘録を簡単に残す。
目標
簡単にするため、ログインパスワードを知っている人間がつつければOKってコトにする。
細かい設定を行いたい場合は、以下を参照。
http://jupyter-notebook.readthedocs.org/en/latest/public_server.html
導入前提
- CentOS7
- Python3.4
- pip3で以下が導入済みであること
- numpy
- scipy
- pandas
- matplotlib
- scikit-learn
- IPython notebook
導入
設定
IPythonを起動して、IPython notebookにログインするときのパスワードを設定する。
ハッシュ化されたパスワードが表示されるのでコピーしておく。
# ipython
In [1]: from notebook.auth import passwd
In [2]: passwd()
Enter password:【ログインパスワード】
Verify password:【ログインパスワード】
Out[2]: 'sha1:【ハッシュ化されたログインパスワード】'
IPythonを終了して、jupyter_notebook_config.py
を編集する。
# vi ~/.jupyter/jupyter_notebook_config.py
jupyter_notebook_config.py
の内容は以下の通り。
c = get_config()
# matplotlibで描画したものがnotebook上で表示できるようにする
c.IPKernelApp.pylab = 'inline'
# 全てのIPから接続を許可
c.NotebookApp.ip = '*'
# IPython notebookのログインパスワード
c.NotebookApp.password = 'sha1:【ハッシュ化されたログインパスワード】'
# 起動時にブラウザを起動させるかの設定(デフォルトは起動させる)
c.NotebookApp.open_browser = False
# ポート指定(デフォルトは8888)
c.NotebookApp.port = 【接続ポート】
接続検証
IPython notebookを起動させる。
# ipython notebook
そして、外部の端末のブラウザよりhttp://【リモートサーバ】:【接続ポート】/tree
で接続する。
するとパスワードを聞かれるので、【ログインパスワード】を入力して、ログインする。
これで、リモートからIPython notebookを使うことが出来るようになる。
new
-> Notebooks Python 3
をクリックし、新規ノートブックを開き、以下の通りに入力を進める。
In [1]: pylab inline --no-import-all
Populating the interactive namespace from numpy and matplotlib
In [2]: x = np.arange(-10, 10, 0.1)
In [3]: y = np.sin(x)
In [4]: plt.plot(x, y)
Out[4]: [<matplotlib.lines.Line2D at 0x7fef3e2e2d68>]
入力したら、以下の画像のようなsin(x)の絵が出力されることを確認する。
コンソールより、Ctrl-C
でサーバをシャットダウンする。
これでたぶん一通りの基本的なものは使えるようになるだろう。
VirtualBoxが正常に動作しなかった件について
MacTypeをインストールしていると、上手に使えないときがあるの備忘録。
そのときはMacTypeを起動し、「プロセスマネージャー」より、以下のプロセスを右クリックから『このプロセスを除外する』を選択する。
- VBoxNetDHCP
- VBoxSVC
- VirtualBox
これでOK。