トップページに戻る

python tips 基礎編

 pythonの文法には、他のプログラム言語と比較すると不自然な仕様が含まれています。
特に注意すべきことをまとめました。


注意が必要な仕様:

大域変数を関数内で使う際の注意: global宣言
To use global variables in function:
 pythonでは、関数内で変数に代入する場合は、局所変数を作成してその変数への代入になります。
そのため、大域変数として宣言されている変数と同じ変数名であっても、局所変数への代入になり、
関数内での代入では大域変数を変えることはできません。
 関数内で大域変数に代入する場合は、globa宣言が必要です。
混乱を避けるため、大域変数はdef function内の最初にglobal宣言するべきです。
  Interpretation of variables defined both global and in function in python is tricky.
To avoid confusion, better use 'global'.
  
   g_value = 1.0
      def func(x):
           global g_value

関数内で定義した関数から、一つ上の関数で定義した変数を参照する場合: nonlocal 宣言
 global宣言は、スクリプト本体の一番外側の変数を参照します。
関数内で定義した変数 a を、その中で定義した関数から参照する場合は nonlocal 宣言を使います。

def func_top():
   a = 1.0
   def func_inside():
        nonlocal a
        print("a=", a)

サイズ指定の配列をリスト型で使う場合の注意
Define n size array by list:
      array = [0.0] * n
   Note: Don't use array = [[0.0]*n]*m for 2D array. 
      For example,
array[0][1] = 1.0 will change all array[i][1] to 1.0. 
      Remind the elements in this list
array[i] are references to the same object "[0.0]*n". 

一次元配列をnumpy.ndarrayで使う場合の注意
・ 一次元配列 aに対しての転置はとれない: a.transpose() == a のまま
 転置を取る場合は、a.reshape((ndim, 1)) を使う
 あるいは、一次元配列に対しても、二次元配列を用いる: 
     a = numpy.empty((ndim, 1))
     at = a.transpose()
=> 転置ベクトルになる
・ 一次元配列同士の *、@ には注意
    a = numpy.array([1, 2])
  
  a * a = [1, 4]: 要素ごとの乗算
  数学通りに内積を取る場合は、
    a @ a.reshape((ndim, 1))
  のはずだが、
    a @ a と、 右の a を転置にしなくても、内積になる。
・ 数学のa・a を計算する場合は、
 numpy.inner(a, a)
 とする方がわかりやすい
・ a^t @ a を計算する場合
は、
 numpy.outer(a, a)
 とする方がわかりやすい (英語のouter productも外積だが、一次元配列の要素ごとの積行列の計算)
・ 日本語の外積は cross product
 numpy.cross(a, b)


基本的な文法:

Use mathematical functions
  from math import exp, sin, cos, tan

range(N1, N2, N3) function:
  generate integer tuple from N1 to N2-1 at N3 step

繰り返し: i = 0 から N-1 まで
Loop: Repeat from i = 0 to N-1
    for i in range(N):
       print(i)
   else:
      ...

繰り返し
Loop: while
   i = 0
    while i < 10:
       print(i)
      i++
   else:
      ...4

条件分岐
Conditional branch
    if a == b:
       print('a = b')
    elif a > b:
       print('a > b')
    else
       print('a < b')

if __name__ == '__main__' trick:
 あるpythonスクリプトを、独立したプログラムとして使うとともに、
モジュールとしても使う場合にこのトリックを使います。
__name__変数には、pythonモジュール名 (スクリプトファイル名から拡張子 .pyを除いた部分)が
入りますが、独立したプログラムとして実行された場合は、"__main__"が入ります。
if文でこの判断をし、__name__ == "__main__" が成立した場合だけ main() 関数を呼び出すように
すると、importされた場合にはmain()が実行されません。
   Use if the python script will be used also for a module.
The following set of script will execute main(x) 
only when the variable __name__ is '__main__',
which is satisfied only when the python script is directly
executed. 
def main(x):
    ...
if __name__ == '__main__':
    main()


関数の定義
Define function
    def func(x):
      y = x
      return x, y


文字列オブジェクトの.formatメソッドによる整形
Format of floating point
    s = f"{val:>12.4f}"
    s = f"{val:12.4f}"
    s = f"{val:12.4e}"
    s = "{:<+12.4f}".format(val)
    s = "{:^12.4f}".format(val)
    s = "{:>12.4f}".format(val)

csv (カンマ区切り) ファイルへの書き込み
Write to csv (comma separated values file)
    import csv
    header = ['x', 'y']
    data = [[0, 0], [1, 3], [2, 5]]
    f = open('out.csv', 'w')
    fout = csv.writer(f, lineterminator='\n')
    fout.writerow([header)
    for row in data:
        fout.writerow(row)
    f.close()