#環境構築あれこれ
こんにちは、Javaおじさんです。
何となく文法もわかってきつつあるので、そろそろDjangoの開発環境もそろえねば、と思っていろいろ情報をあさっているのだけれど、とあるページでこんなことを読んで「マジ?」ってなった。
Pythonエンジニアは、ほぼこれ(PyCharm)を使っていると言っても過言ではありません。
どっかにPythonの開発環境に関する比較記事載ってないかな(他力本願)
と思って検索したら結構な率でPyCharm推しだった。
んーでも有償版と無償版で機能制限付いてるみたいだし、とりあえず今のところVisual Studio Codeで不便感じてないからいっかな。
ま、それはともかく。
一応この辺を見つつセットアップをしているのだけど、Vagrant使う必要あるのかなあという気がしてきている。
いやまあ諸々の関係上使った方がたぶんいいんだと思うんだけど、開発環境としてWindowsのAnacondaでコード書いて実行環境としてVagrant環境にアップロードするとか考えるとちょっと手間じゃないかなという気もしていて。特にDBからむテストコードを書く場合にいちいちアップロードしてテストしてとかやってるとコスト高い気がするのよね。
CI環境作らんとだめかしらね。でもそれはそれでむしろ逆に重くないか?
とか考えつつ昨日から試行錯誤している。
#リストと可変性
とはいってもマルチタスクができるほど器用ではないのでテキストの読み進めの方をメインに進めてはいる。
今日は「5-2 リストと可変性」を読んでいる。
リストとタプルの違いとしては以下。
- タプルの初期化には()を使うのに対してリストは[]を使用する。[1,2,3,4][1:3][1]とかいう表現もできる。
- リストの場合は要素が1つでもタプルと違って,は不要。まあこれは冷静な話をすると構文解析の問題なので是非もないね。
- タプルは不変、リストは可変
最後のポイントは以前コメントでも指摘してもらってた「メソッドは副作用を伴う」という話にもリンクしている。
つまるところリストは可変なので、副作用を伴う(=内部状態を変化させる)メソッドを使ってリストそのものを書き換えることが可能になる。+や*といった演算子は副作用を伴わない(=内部状態を変化させない)ため、リストに対してこれらの演算子を使用すると新しいリストを作り出して返してくる。
タプルの場合不変なので、そもそも内部状態を変更するためのメソッドそのものを持たない、ということになる、のかな?その辺の言及がこのテキスト明確でないからいまいち断言しづらいんだけど。
たぶん関数型プログラミングではこの副作用を伴う/伴わないって話が重要になってくるんだろうなーというのはどっかで聞きかじった話。おそらく後で出てくる。
#リストのクローン
ループの中でリストを変更する場合、以下の方法でリストのクローンを作って変更の影響を受けないようにする。
- スライス表記を使ってリストの一部をコピーする。
- list(L)でリストの複製を返す。(まんまコピーコンストラクタですな)
- 可変のオブジェクトが含まれる場合は標準ライブラリcopyをインポートしてcopy.deepCopyを使用する
~~コードは後で書こう。~~書いた。
import copy
source = [1, 2, 3, 4, 5]
print('id(source) =', id(source))
#スライス表記を使ったクローン
for value in source[1:3]:
print(value)
print()
#list(L)を使ったクローン
copied = list(source)
for value in copied:
print(value)
print('id(copied) =', id(copied))
print()
#copy.deepCopyを使ったクローン
deep = copy.deepcopy(source)
for value in deep:
print(value)
print('id(deep) =', id(deep))
実行結果は以下の通り。
id(source) = 1242503195016
2
3
1
2
3
4
5
id(copied) = 1242502800136
1
2
3
4
5
id(deep) = 1242503195656
#リスト内包
与えられた演算をある順序型の値(例えばリストの要素に対して)に施した結果を各要素とする新しいリストが作り出される
ということらしい。
でもってfor節の中には1つ以上のif文やfor文を続けることも可能で、条件を満たしたデータのみを抽出することも可能である、と。ふむ。
~~これもコードは後で書こう。~~書いた。
def isPrime(target):
"""簡単な素数判定。素数ならTrue、素数でなければFalseを返す"""
for n in range(2, target):
if target%n == 0:
return False
return True
#リスト内包(単純な演算)
simple = [x**2 for x in range(1, 6)]
print(simple)
#リスト内包(条件によるデータ抽出:素数の2乗をリストに抽出)
onlyPrime = [x**2 for x in range(2, 11) if isPrime(x)]
print(onlyPrime)
抽出したデータを2乗しているのは特に意味はなくて演算できますよと示したかっただけ。
実行するとこんな感じ。
[1, 4, 9, 16, 25]
[4, 9, 25, 49]
三項演算子並みにトリッキーなコードではあるかなー、という印象。
でもたぶんフィルターとして便利なんだろうな。
誰かほかの人がそのコードを読む必要があるかもしれないし、その時に「巧妙」であることは望ましくない場合もあることを覚えておこう
基本的にコメント重要なのだろうな、というのはあるね。
今日はここまで。