はじめに
Matlabで今までやってきましたが,機械学習を行う上で,プログラミングを本格的にやってみようと決意して,はや2か月がたちました
遊びで機械学習をやってみたくて,0からはじめるDLなどを読破して,アルゴリズムの面白さに気づき,AtcoderでC問題とD問題に苦戦している現在です.蟻本も読み進めている最中,Tensorflow系の本も読んでみてます
そこで,今までPythonで苦戦したことをまとめます
目的
Pythonに必要とされる知識の共有(初心者)
特にMatlabというものから移行される方
Pythonのversion
python 3.6.4
変数宣言
copyというやつ
これは一番難しいところではないでしょうか!
immutable と mutableについては後で触れます.とりあえずは基本の考え方
Pythonは変数を
a = 1
b = a
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
#Result
#a_address = 1620864480
#b_address = 1620864480
のように宣言すると,同じアドレスが入ります
よく言われるように名札を数に貼り付けてます.
つまりこの場合はa, bが同じ場所を指しているのは明確です.
で,immutableなら問題ありません.コピーしてみましょう
a = 1
b = a
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
a = a + 1
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
#Result
#a_address = 1620864480
#b_address = 1620864480
#a_address = 1620864512
#b_address = 1620864480
いわゆるMatlabっぽく動きました.変数を宣言しなくても,そのままそこに入ります.そしてそれを扱えるということです.
で,ここまでが分かるとimmutable と mutableの話につながります
mutableは配列ですが,
次のようなケースを考えてみましょう
a = [1]
b = a
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
a.append(2)
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
print('a = {0}'.format(a))
print('b = {0}'.format(b))
#Result
#a_address = 1706568184776
#b_address = 1706568184776
#a_address = 1706568184776
#b_address = 1706568184776
#a = [1, 2]
#b = [1, 2]
これが一番危険なパターンですね
よく考えると普通なのですが,初心者だとやりがちです.
こんな例もあります
a = [1]*2
b = a
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
a[0] = 2
print('a_address = {0}'.format(id(a)))
print('b_address = {0}'.format(id(b)))
print('a = {0}'.format(a))
print('b = {0}'.format(b))
#Result
#a_address = 2181161940040
#b_address = 2181161940040
#a_address = 2181161940040
#b_address = 2181161940040
#a = [2, 1]
#b = [2, 1]
で,何をどう気をつけるべきなのか?
変数同士を=でつなげた場合は,いったんはそれらが同じものを示していると考えてください!!!!
そのあとにmutableやimmutableうんぬんで話が変わってきますので
これにつきると思います
前に書いたNNのプログラムはこれで動きませんでした.
もし,コピーしたい場合は
import copy
でcopyやdeepcopyを使ってください
関数におけるもの
さて,この問題は関数においても発生します
pythonは関数が,参照渡しです.なので変更されたら変更されます
ご指摘いただいたように,pythonは関数が,値渡しだそうです.勘違いしてました....
”値(オブジェクト)への参照値を渡します。” しっくりきました!ありがとうございます.
ただし,配列などのmutableなものですが
以下を見てみてください
def sample_int(a):
a = 1
def sample_array(b):
b[0] = 1
if __name__ == '__main__':
a = 2
print('a = {0}'.format(a))
sample_int(a)
print('a = {0}'.format(a))
b = [0, 0]
print('b = {0}'.format(b))
sample_array(b)
print('b = {0}'.format(b))
#Results
#a = 2
#a = 2
#b = [0, 0]
#b = [1, 0]
はい...
こういうことです.
まぁそもそもやっていることが不自然なので仕方がないようにも思います!
・return で別の値を返してそれを使う作戦
・タプルにしてから渡す
がメインの手法だと思います
ファイル読み込み
苦戦しました...
まず,ファイルを読み込む→処理→書き出し という作業はできないと企業のコーディングテスト含め,絶対受かりません(落ちまくりました)
単純なことですが,できるようになった方がいいと思います.
僕はmatlab出身なので,(Python育ちになりかけてますが),csvとtxtを読み込む機会が多いのでその2つをまとめておきます(長くなったのでcsvは次回にします)
txtで簡単にやる場合
ワンポイントテクニック
これよくatcoderとかでも使いますが文字列をリスト化すると分かれてくれます
a = input()
#aaaと入力
b = list(a)
#['a', 'a', 'a']
書き込み
txtを簡単に読み書きするにはopenを使います
f = open('sample.txt', 'w')
f.write('test')
当たり前ですが,writeの引数はstrです
さて,改行して書きたいときは,
f = open('sample.txt', 'w')
f.write('test')
f.write('test_2')
f.close()
これだと,くっついて出力されてしまいます
なので,\nで区切るか,(これだとめんどくさいので)
f = open('sample_2.txt', 'w')
f.write('test\n')
f.write('test_2')
f.close()
または
f = open('sample_3.txt', 'w')
text1 = 'I am a dog'
text2 = 'You are a cat'
text3 = [text1, text2]
text = '\n'.join(text3)
f.write(text)
f.close()
のようにしてもよいです.こっちの方がスマートですね.
これだと改行して出力されます.
ちなみにwritelinesはstrの配列を渡すとそれをそのまま書いてくれますので!(改行はされません)
上書きしたいなという人は,'w'を'a'にすれば追記モードになります!
読み込み
同じくopenでよみこみますが,readを使うとこうなります(まるごと読み込まれます)
ここで注意点はスペースと改行文字\nも読まれます
#sampleには aaa\nbbb となっているとします
f = open('sample.txt', 'r')
a = f.read()
a = list(a)
print(a)
f.close()
#出力は['a', 'a', 'a', '\n', 'b', 'b', 'b']
なので分けたい場合は
#sampleには aaa\nbbb となっているとします
f = open('sample.txt', 'r')
a = f.read()
a = list(a.split('\n'))
print(a)
f.close()
#出力は['aaa', 'bbb']
とすれば良いです.では,readlineとreadlinesをどう使えばよいでしょうか?
readlinesはまるごと読まれます(改行文字も含まれます)
readlineは1行のみです
全部読みたい場合は,while文かfor文で回してください
プログラムをみてみます
#sampleには a a a\nb b b となっているとします
f = open('sample.txt', 'r')
a = f.readlines()
a = list(a)
print(a)
f.close()
#出力は['a a a\n', 'b b b']
#sampleには a a a\nb b b となっているとします
f = open('sample.txt', 'r')
a = f.readline()
print(list(a))
f.close()
#出力は['a', ' ', 'a', ' ', 'a', '\n']
なので,これらを用いれば改行と空欄(スペース)を区切って値を取得できます
replaceを用いていますが,stripでも良いです
#sampleには a a a\nb b b となっているとします
f = open('sample.txt', 'r')
a = f.readlines()
print(list(a))
b = []
for i in a:
b.append([i.replace('\n','').replace(' ','')])
print(b)
f.close()
#出力は['a a a\n', 'b b b']
#[['aaa'], ['bbb']]
f = open('sample_3.txt', 'r')
b = []
a = f.readline()
while a:
a = a.strip()#間は消されませんので
b.append([''.join(a.split())])
a = f.readline()
print(b)
f.close()
になります
最後に
pythonはかなりわかりやすい言語ですが,慣れるまで頑張ります.
次回はcsvについて書いてみます
その次はアルゴリズムについてや,NNについてもそのうち書いていきます
Twitter:https://twitter.com/ShunichiSekigu1
github:https://github.com/Shunichi09