pythonメニュー

Pythonの基本

基本的なデータ表現の規則

インタープリタで、起動した時は会話的に進められる。
以下はpythonのコマンドを実行したの実行例で、>>> がプロンプトです。
基本的に改行が文の終わり。「\バックスラッシュ」か括弧を使うと改行あっても文を継続できます。
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 3-2
1
>>>  3-2
  File "<stdin>", line 1
    3-2
    ^
IndentationError: unexpected indent
>>>(1+2*3)/2
3.5
>>> "python" + 'は面白い' # 文字列同士であれば + で連結
'pythonは面白い'
>>> "python" + 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
>>> quit() #終了コマンド
太字字が入力で計算結果が式入力の直後に表示されている。
先頭に半角があると、エラーになっています。(前方の空白は特別な意味があります。)
文字列定数は(シングルクォーテーション)と(ダブルクォーテーション)のどちらでも可で違いがない。
文字列同士の連結も可能であるが、数字との文字列の連結はできないので、上記ではエラーが表示されています。
それを行い場合は、数字を文字列にstr関数で変換してから行えばよい。「"python" + str(3)

データ型(type)

データ型を調べるtype関数があります。以下の実行結果から基本的に使える型を推測してましょう。
>>> type(1)
<class 'int'>
>>> type(2)
<class 'int'>
>>> type(2.0)
<class 'float'>
>>> type('2.0')
<class 'str'>
>>> type(1==1)
<class 'bool'>
>>> type([ [1], [2,3] ])
<class 'list'>
>>> type( ( (1), (2,3) ) )
<class 'tuple'>
>>> type({ 'key': 'ID001' })
<class 'dict'>
>>> type(set({ 'a','b','ab','a', 1, 1.5e-2 }))
<class 'set'>
>>>
上記の[ ] で囲む表現はリストと呼ばれます。( 配列のようなものです。 )
また、( ) で囲む表現はタプルと呼ばれます。( 配列のような操作ができますが、初期化後の変更はできません )
基本的なシーケンス型は、リスト、タプル、そしてもう一つ range オブジェクトがあります。
range 型は、直接的な数値などのシーケンスを表し、一般に for ループにおいて特定の回数のループに使われます。

算術演算

次の実験で分かるように、べき乗は ** の演算を使います。なお、「 # 」からその行末までがコメントです。 
>>> 2 ** 8 
256
>>> 10 / 2 # 整数同士でも、割り算の結果は float型になる。(IEEE-754 浮動小数点演算 C言語 double型と同じ)
5.0
>>> 10 // 2 # 整数の結果を出す演算子は「//」です。
5
>>> [ 10.5 % 5 , 10 % 4 , 10.525 % 0.5 ] # 余りの演算は、floatに使えて、int に使うと、結果のint
[0.5, 2, 0.025000000000000355]
>>> math.sqrt(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>>
最後の4の平方根を求めている所でエラーが生じていますが、これ自体がエラーではありません。 次のように、モジュールをimportしてからでないと、使えない関数があるのです。

imort mathモジュールを使った演算

モジュールは Python の定義や文が入ったファイルで、mathは標準モジュールです。 そして、モジュールは import 命令により取り込んで、使えるようになります。
また delで 開放するすることもでします。以下でmathの取り込んで、算術機能を使う例を示します。
>>> import math
>>> math.sqrt(4)
2.0
>>> type( math )
<class 'module'>
>>> math.sin( math.pi / 2 ) # 引数はラジアンです。
1.0
>>>
上記の math.pi は、 π = 3.141592... (円周率)です。
他にも、math.e e = 2.718281... (自然対数の底)などたくさん定数も定義されています。

変数

後述データ型も含めて、変数に記憶して後から使えます。型などの宣言をしないですぐ使えますが、設定していない変数を利用するとエラーです。
>>> a=7 # 変数aに記憶(定義することで、以降使えるようになる。)
>>> a # 変数を参照<
7
>>> a / b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined	bが定義されていないためのエラー
>>> b=2
>>> a/b
3.5
>>> a, b = 100, "1111"  # 変数aとbを、それぞれ異なる値で設定している。 
>>> a + int(b, 2)
115
>>>
a+bは型が違うためのエラーになるので、int(b, 2)により、bの文字列を整数に変換(基数を2として)しています。
int(文字列 [,基数] ), long(文字列 [,基数]), float(文字列 [,基数])などの関数で、文字列を数値に変換できます。
str(データ)で、文字列変換できます。
整数をhexやoct、binなどの文字列へ変換関数もあります。それぞれ16進、8進、2進文字列への変換です。
また、文字コードから文字への変換にはchr関数を使います。例えばchr(48) で'0'、chr(71)で'G'の文字列が得られます。
この逆変換には、ord関数を使います。例えばord('0') で48、ord('G')で71の数値が得られます。
なお、バイトシーケンスという表現があって、「str( b'\x30\x47\x3a\x53')」で、'0G:S'の文字列が得られます。
デフォルトエンコードがutf-8なので、「str( '\u0030\u0047\u003a\u0053\u3042')」で、'0G:Sあ'の文字列が得られます。

input関数によるキー入力

test.pyのファイル名で以下のファイルを作った場合の例です。(UTF-8のキャラセットでファイルを保存)
# coding: UTF-8

name = input('文字列入力。>>>  ') #キー入力
print( type(name) )
print( name )
コマンドプロンプトで、次のように実行できます。
Z:\> pyyhon test.py
文字列入力。>>>  あいう

文字列

日本語も使えるが、先行に次のようなcodingのコメントが必要(ファイル保存のエンコードに合わせます)
# coding: windows-31j
# coding: UTF-8
Python はの字列定数は(シングルクォーテーション)と(ダブルクォーテーション)のどちらでも可能で、どちらもエスケープ文字を置換して出力する。
置換しない場合は文字列の前にRAWの意味の r または R をつける。r'abc\n123'

文字列は配列演算子で文字を指定できる。
print('ABCDEF'[2])   # 「C」を表示
print('ABCDEF'[1:3]) # 「BC]を表示
print('ABCDEF'[1:])  # 「BCDED]を表示
print('ABCDEF'[:3])  # 「ABC]を表示

+の演算子で連結する場合、左右のオペランドがストリングでなければなりません。また 「文字列 * 数値」で数値のだけ連結した文字列が作れます。以下に例を示します。
s="ABC"
n=5
print(s + str(n) ) # 「ABC5」を表示する。 strは2進文字列に変換
print(s + bin(n) + "," + hex(n)) # 「ABC0b101,0x5」を表示する。 binは2進文字列に、hexは16進文字列に変換
print(s * n) # 「# 「ABC0b101,0x5」を表示する。 」を表示する。
print( int('101', 2) * 2) # 逆変換で、文字列から数値へ変換する例で、int関数の第2引数で基数を指定している。'101'は5で、それを2倍した10が表示される。

文字列メソッドのstr.format()を使った文字列生成
d = 0b11110000 # 240の値をdに記憶
print('dは{}です'.format(d))           # 「dは240です}を表示する。
print('dは{:6}です'.format(d))         # 「dは   240です}を表示する。
print('dは{}です'.format(d/100))       # 「dは2.4です}を表示する。
print('dは{:9.5f}です'.format(d/100))  # 「dは  2.40000です}を表示する。
print('dは{:<9.5f}です'.format(d/100)) # 「dは2.40000  です}を表示する。<の記号は左寄せの指定です。
print('{:b}は{}です'.format(d, d))     # 「11110000は240です}を表示する。
print('{1:b}は{0}です'.format(d, d))   # 「11110000は240です}を表示する。{}の中の番号で、引数の位置が指定できます。
print('{0}は、{1:b}で、{2:o}で、{3:x}です'.format(d,d,d,d))     # 「240は、11110000で、360で、f0です}を表示する。
#    ( 10進 2進  8進 16進 の変換例です。)
print('貯金は{:,}円です'.format( 12345678 )) # 「貯金は12,345,678です」を表示する。
import datetime
print('{:%Y-%m-%d %H:%M:%S}'.format( datetime.datetime.now() ) ) # 現在時刻の表示例「2018-07-29 15:48:41」
なお、ビルトインのformat関数もあります。str.format()と下記で比較して実行すている例です。
>>> "{0}の2進は{1:010b}".format(255,255)
'255の2進は0011111111'
>>> format(255,'010b')
'0011111111'
format関数の第2引数は、'0b’、'0o’、'0x’のような文字列指定です。数字は文字幅です。

ようく使われるメソッド紹介
s="   AB   " # javaのtrimメソッドに相当するstripを使う
s=s.strip() # sに記憶されるのは"AB"で、前後の空白文字は取り除かれる。

split()を使うと、引数として渡した区切り文字で文字列を区切ったリストが作られます。引数を空欄にした場合は空白で分割されます。
変数 = 文字列.split(‘区切り文字’)
また、この逆関数で引数の文字列のリストを‘区切り文字’で連結文字列を生成するjoinメソッドがあります。
s="ABC: 123\nX, Y=7, 8\nZ=99"
lines=s.split("\n")
print(lines[0]) # 「ABC: 123」を表示
print(lines[1]) # 「X, Y=7, 8」を表示
print(lines[2]) # 「Z=99」を表示
items=lines[0].split(":")
print(items[0], int(items[1]) ) # 「ABC 123」を表示
print('-'.join(["AB","CD","EFG"]) #「AB-CD-EFG"」を表示

配列(リスト)

[ ]を使って表現できます。2次などn次配列が可能です。
配列の単純な代入(コピー)はポインタのコピーなので、コピー先を変えるとコピー元も変わります。
実体をコピーする場合は z = w.copy() のようにcopy関数を使用します。
>>> a=["aa",2]
>>> b=["bb",3]
>>> a+b+[1,] # + で連結できる。
['aa', 2, 'aa', 3, 1]
>>> w=[5,2,3,4,1,[9,8],5]
>>> w
[5, 2, 3, 4, 1, [9, 8], 5]
>>> w[0]
5
>>> w[5]
[9, 8]
>>> len(w) # リストの長さ
7
>>> z=w # 参照(ポインタのコピー)
>>> z2=w.copy() # 複製したリストをz2に参照させる。 (以下はその確認)
>>> w[0]=99
>>> z
[99, 2, 3, 4, 1, [9, 8], 5]
>>> z2
[5, 2, 3, 4, 1, [9, 8], 5]
>>> list(range(5,50,5)) # listのキャストで配列を生成
[5, 10, 15, 20, 25, 30, 35, 40, 45]

スライス

なお、.copy関数を使わなくても、a[ スタート添え字 : エンド添え字 : ステップ数] の表現で配列のある部分要素をコピー参照できます。 これはスライシング(slicing)と呼ばれる記法です。(複数要素を一括して変更も可能)
スタート添え字や、エンド添え字、ステップ数は省略表現できます。またマイナス表現で、除く使い方ができます。
>>> a=[1,2,3,4]
>>> a[1:3] # a[1] から a[3-1]の部分配列生成
[2, 3]
>>> a[1:] # a[1] から 最後まの部分配列生成
[2, 3, 4]
>>> a[:3] # 先頭 から a[3-1]の部分配列生成
[1, 2, 3]
>>> a[:-2] # 先頭 から 後ろの2つの要素を除いた部分配列生成(負の数にすると後ろから数える)
[1, 2]
>>> a=[1,9,2,8,3,7,4,6,5 ]
>>> a[1:9:2] # [1]から[8]までを2のステップで抽出した配列生成
[9, 8, 7, 6]
>>> a="192837465"
>>> a[1:9:2] # [1]から[8]までを2のステップで抽出した文字列生成(文字列でも操作可能)
'9876'
>>> a[9:1:-2] # [8]から[1]までを-2のステップで抽出した文字列生成(ステップが負なので、逆方向にステップ)
'5432'
>>> [1,2,3,4,5][::-1] # 全てを-1のステップにすると、逆順にする
[5, 4, 3, 2, 1]
なお、要素数を超える位置を指定してもエラーにはならず無視される。
またスライスで選択した範囲にリストを代入することが可能(リストでない値の代入はできません!エラー)
>>> a = [3, 4, 5, 6, 7, 8, 9]
>>> a[2:5] = [200, 300, 400]
>>> a
[3, 4, 200, 300, 400, 8, 9]
>>> a = [3, 4, 5, 6, 7, 8, 9]
>>> a[2:6] = [200, 300, 400]
>>> a
[3, 4, 200, 300, 400, 9]
>>> a = [3, 4, 5, 6, 7, 8, 9]
>>> a[2:6] = [] # 部分的な削除
>>> a
[3, 4, 9]
>>> a[1:1] = [8,7,6] # リストの挿入操作
>>> a
[3, 8, 7, 6, 4, 9]
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[0:10:2]
[0, 2, 4, 6, 8]
>>> a[0:10:2] = [-1,-2,-3,-4,-5]
>>> a
[-1, 1, -2, 3, -3, 5, -4, 7, -5, 9]
>>>  a[0:1]=0
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can only assign an iterable


リストには末尾に追加するappendや、指定添え字前の位置に追加するinsert、そして末尾(添え字指定で任意の位置)の削除のpop、 複数の要素の削除のdel、指定した値と一致した場合に削除するremove、全ての要素の削除clearがあります。
また、指定の値を持つ要素のインデックスを得る場合はindexメソッド、 指定の値を持つ要素がいくつ含まれるか調べるばあは、countメソッドを使います。
また、指定の値を持つ要素が存在するか調べる場合は in演算子が使えます。
なお、末尾の操作は速くappendやpopがありますが、先頭要素を抜き取る処理は存在しません。
他の要素をひとつずつずらす必要がある場合、遅くなってしまうからでしょう。 ですから待ち行列を単純に利用する場合は、不向きです。
その場合は、「from collections import deque」と宣言して、dequeを使いましょう。
a=[1,2,5,3,4,5,6,7,5,8]
a.index(5) # 2 の出力結果 
a.index(5,2+1) # 5 の出力結果
a.index(5,5+1) # 8 の出力結果
a.index(5,8+1) # 存在しないので次の実行エラーが生じます
Traceback (most recent call last):
  File "", line 1, in 
ValueError: 5 is not in list

print( a.count(5) ) # 5が3つあるので 3 の結果が得られます。
print( 5 in a ) # aのリストに5があるので、 True の結果が得られます。

タプル

タプルはリストと同じコレクションの1つで、生成以外は、配列に似た操作が可能。但し要素の変更はできない。
タプルを定義するには括弧( )を使い、この中で要素をカンマ(,)で区切りで並べます。
data = (1, 2, 3, 4, 5) # タプルの生成
print(data[0], data[2]) # 表示結果:1 3
data2 =data + (6,7) # タプルの結合
print(data2) # 表示結果:(1, 2, 3, 4, 5, 6, 7)
((a,b),(c,d))=(1,2,3,4) # 一括代入にも使える

アンパック

アンパックはリストや、タプルから複数の変数に展開して代入するたもの仕組みです。
次のような代入処理が可能です。
a,b,c =[1,3,2] #アンパックして代入 aに1、aに3、aに2、と代入
x,y,z =(10,20,99) 
(x,y),z = ((10,20), 99) # このような構造でも可能

ディクショナリ (辞書)

ハッシュテーブル、連想配列に相当するもので、キーとなる文字列で、任意の値やオブジェクトを記憶でき、キーの文字列で参照できます。
生成は { キーとなる文字列 : 記憶したい値 } のように、 { } で : 使った表現です。
>>> t['ID01']=1 # tのディクショナリ変数を用意しないで使うとエラー
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 't' is not defined
>>> t={'ID01': 1} # ディクショナリの生成してtに参照させる表現
>>> t['ID02']=2
>>> t
{'ID01': 1, 'ID02': 2}
>>> t['ID01']
1
>>> t.keys() # 辞書オブジェクトに含まれているキーのリスト
dict_keys(['ID01', 'ID02'])
>>> t.values() # 全ての値を要素としたリスト型を取得
dict_values([1, 2])
>>> 

ブーリアン

True または False の何れかを表現するものです。
a=[2,5,4,9]
b=[ x > 4 for x in a ]
b # [False, True, False, True] の表示

制御構造表現の規則

if制御

filenameの文字列内にある文字列が含まれているかの判定例 (コロンと、インデントが大事です。)
if '.' in filename:
    print("filwenameの文字列に、'.'の文字が含まれるか?")
elif filename in 'dic' :
    print("filwenameの文字列に、'dic'の文字並びが含まれるか?")
else :
    print("上記の条件で、いずれにも合わない場合の処理")

なお、式の表現の条件処理も可能で、以下では変数aが0以上でTrueの結果になる表現です。
b = True if a >= 0 else  False
つまり、[次のifが成立した時の結果となる式] if 条件 else [不正立の時の結果となる式] と表現します。

繰り返し

for 例1
>>> for x in range(1, 5):
...    print( x , " " ,  end="") # 末尾のendオプションに何も付加しない指定をすると改行なしで出力できる。
...
1  2  3  4  >>>
>>> for x in range(4, -1, -1): # 第3引数で、-1の増減で、マイナスにしている。
...    print( x , " " ,  end="") # 末尾のendオプションに何も付加しない指定をすると改行なしで出力できる。
...
4  3  2  1  0  >>>
>>> for x in range(5)[::-1]: # スライスで1,2番目で指定せずstepに-1を指定すると、シーケンスの逆順(のコピー)にできる
...    print( x , " " ,  end="") # 末尾のendオプションに何も付加しない指定をすると改行なしで出力できる。
...
4  3  2  1  0  >>>
>>> for x in list(reversed(range(5))): # 逆順のイテレータを返すreversed関数を使う
...    print( x , " " ,  end="") # 末尾のendオプションに何も付加しない指定をすると改行なしで出力できる。
...
4  3  2  1  0  >>>
for 例2
>>> for a in range(10,31,3): # 3の増加分を使う (なお、rangeで生成できるのは整数のみ)
...    print(a , " " , end="")
... 
10  13  16  19  22  25  28  >>> 
>>> for a in range(10,32,3):# 31のaを使うために終了値を32にしている。
...    print(a , " " , end="")
... 
10  13  16  19  22  25  28  31  >>> 
rangeで生成できるのは整数なので、少数点を指定すると、
TypeError: 'float' object cannot be interpreted as an integer」となってできません。
上記で、刻みに0.5使いたい場合のテクニックとして、次の方法があります。
for n in [0.1*x for x in range(100,310,5)]:
また、後述するNumpyのarangeを使う方法もあります。

for 例3 2次配列で、各要素を繰り返で使う。
>>> for x in [1, [2 , 3, 4],[ 5],[ 6, 7],8]:
...    print(x)
...
1
[2, 3, 4]
[5]
[6, 7]
8
>>>
while例1
>>> x = 0
>>> while x < 3:
...    print( x , ", " , end="") # 末尾のendオプションに何も付加しない指定をすると改行なしで出力できる。
...    x += 1
...
0 , 1 , 2 , >>>
while例2
>>> a=[ [1], [2 , 3, 4],[ 5],[ 6, 7] ]
>>> y=0
>>> while y < len(a):
...    x=0
...    while x < len(a[y]):
...       print( a[y][x] , " " , end="")
...       x += 1
...    y += 1
...
1  2  3  4  5  6  7  >>>

イテラブル iter 、next、enumerate 、zip、map

イテレーションとはリストなどを対象にして「順番にアクセス」すること言います。
forの制御がそうです。イテレーション可能な構造のオブジェクトをイテラブル(iterable) なオブジェクトといいます。
つまり、forは「for 変数 in イテラブル(iterable) なオブジェクト:」の表記で「順番にアクセス」する繰り返しができます。
このイテラブル(iterable) なオブジェクトを実現するクラスがいくつか(range, iter など)用意されています。
そして、「__next__というメソッドをもっているオブジェクト」がイテレータで、iter関数で生成できます。
iter( リストやタプル ) でイテレータオブジェクトが得られて、next関数で操作できます。
d=[5,2,3,4]
i=iter(d)  # イテレータオブジェクトが返される。
i # 例えば 次の表示で <list_iterator object at 0x00000263CD793668> になる。
next( i ) # 5の表示
next( i ) # 2の表示
next( i ) # 3の表示
i=reversed(d)  # 逆操作のイテレータオブジェクトが返される。
next( i ) # 4の表示
next( i ) # 3の表示
next( i ) # 2の表示
next( i ) # 5の表示
next( i ) # 終端を超えた操作でTraceback (most recent call last):  Fi・・・・  StopIterationのエラー表示
上記最後は、next関数の実行で次の情報がないために実行エラーになった例です。
次のデータが存在しない時、実行エラーにしないで指定の値がnext関数の戻り値にしたい場合、指定の値を第2引数で指定します。
例えば、-1を戻り値にしたい場合、 next( i , -1 ) と実行させます。
for の制御構造などは、内部でイテレータの仕組みを利用した繰り返しがなされます。(whileで無理やり使った。)
for v in [5,2,3,4]:
   print(v) # 5 2 3 4 と表示します。
for v in iter([5,2,3,4]):
   print(v) # 5 2 3 4 と表示します。
i =iter([5,2,3,4])
while True:
   try:
      v = next(i) # 5 2 3 4 と表示します。
      print(v)
   except StopIteration: break

enumerate関数の利用

enumerateを使うと、インデックスを付加したタプルリストが得られる。
w = ["Tue","Wed","Thu","Fri","Sat","Sun"]
e=enumerate(w, 1) # 第2引数で指定するインデックスのスタート値を指定できる(省略すると0から)
print(e ) # 表示例 <enumerate object at 0x0000015C0E501708> 
print(list(e)) # 表示; [(1, 'Tue'), (2, 'Wed'), (3, 'Thu'), (4, 'Fri'), (5, 'Sat'), (6, 'Sun')]
for s in enumerate(w): # (0, 'Tue')(1, 'Wed')(2, 'Thu')(3, 'Fri')(4, 'Sat')(5, 'Sun')と表示
   print(s, end="")

zip関数の利用

zipを使うと、個々の要素をタプルにしてまとめたイテレータを返します。
x=("tokyo", "chiba")
w=(1,  0.6)
y=zip(x, w) #yにzip objectが記憶 これは個々の要素をタプルしたイテレータを返します。
for d in y: 
   print(d) # ('tokyo', 1) と ('chiba', 0.6)を表示

map関数の利用

map関数は、第1引数の関数を第2引数のリストに適用し、イテレータを返す。
m=map(str, [5,2,3,4])  # 文字列へ変換するstr関数と、整数のリストを引数にしてmapを生成
m # 例えば <map object at 0x0000023E245B1EF0>のような表示
type(m) # <class 'map'>の表示
a=list(m) # mapをリストに変換
a # ['5', '2', '3', '4'] の表示
list(m) # マップから一度リストを生成すると、マップは空になることに注意 表示→[]

ジェネレータ

ジェネレータの生成例を次の一行目で示します。
>>> g=(n for n in range(5))
>>> g
<generator object <genexpr> at 0x000001D57398AB48>
>>> for v in g: print(v)
...
0
1
2
3
4
>>>

関数定義

関数定義と利用例

def sub(a,b,c):
   y = a + b + c
   print( type( y ) )
   return y

y = sub(1,2,3) 	# 「class 'int'」の表示
print(y)		# 「6」の表示
print( sub(1) )	# 「TypeError: sub() missing 2 required positional arguments: 'b' and 'c'」のエラー
print( sub("a", "b" ,"c") ) # 「class 'str'」と 「abc」の表示


def sub(a,b=10,c=100): # デフォルト引数を設定した関数定義
   y = a + b + c
   print( type( y ) )
   return y

print( sub(1) ) 		#「111」の表示
print( sub(1,20) ) 		#「121」の表示
print( sub(1,c=200) )	#「211」の表示
print( sub(1,c=200, b=50) )	#「251」の表示 (引数の順番を変更しても可能)

def sub2(a=[]):
   a.append(1) # デフォルト引数の配列に、1の要素を追加する変更を行っている。
   print(a)

sub2()		#「 [1] 」の表示
sub2()		#「 [1, 1] 」の表示
sub2(['A'])	#「 ['A', 1] 」の表示
sub2()		#「 [1, 1,1 ] 」の表示
最後のsub2では、デフォルト引数のオブジェクトを内部で変更している処理の例があり、注意が必要です。
不思議な挙動に見えますが、これはデフォルト引数が作られるタイミングは「関数が呼び出される時」ではなく 「関数が作成された時」だからということです。

lambda (ラムダ式)

これは、名前を付けないシンプルな関数と言えます。
関数を変数に記憶して呼び出すことができますが、ラムダ式を変数に代入して、 それをら実行させる芸当が可能になります。
これにより、例えば関数の引数を与える箇所で、ラムダ式を使ってデータを加工して 引数に渡すような使い方ができます。
以下で具体的に、def文による関数定義とラムダ式の一般的表現を以下に並べて比較します。

def 名前(引数, 引数, ...):  # 関数定義例
    return 式

名前 = lambda 引数, 引数, ... :   # ラムダ式定義例

実際に作った例で、まず関数の定義と利用例を示します。
def add(a,b=1):
   return a+b

func=add
print( func(5,3) )
print( func(5) )
上記をラムダ式で実現した例を以下に示します。
func=lambda a, b=1  :  a + b
print( func(5,3) )
print( func(5) )
関数引数で利用したラムダ式例を示します。
list( map( lambda a :True if a >= 0 else  False, [ 20 , -10 , 5 ]) )
# 実行結果:[True, False, True]
map関数は、第1引数が関数(ラムダ式を含む)、第2引数がリストで、 リストの各要素を関数で変換したmapオブジェクトを返します。
それをlistに変換していますが、これでラムダ式の条件判定結果のリストに変換しています。

global 変数

次のように関数の外側で宣言した変数は、複数の関数内で参照可能です。
abc=123 # 関数の外側で宣言した変数で、グローバルスコープになる

def disp():
   print( abc )

disp() # 123 を表示
関数の中で、単に代入した変数は、ローカル変数です。
abc=123 # 関数の外側で宣言した変数で、グローバルスコープになる

def disp():
   abc=999 # ローカル変数を作っている
   print( abc ) # 999の表示

disp()
print( abc ) # グローバルのabcの123を表示(上記関数で変更されていない。)
上記のように、関数内でグローバルを変更できていません。
変更のためには、次のように関数の外側で宣言した変数するためには、globalを使います。
def disp():
   global abc # グローバルスコープの変数を変更している。
   abc=999 # グローバルスコープの変数を変更している。(関数の外側で宣言した変数は、どこに在ってもよい)

abc=123 # 関数の外側で宣言した変数で、グローバルスコープになる
print( abc ) # グローバルのabcの123を表示
disp() # 関数内で、グローバルのabcを変更
print( abc ) # グローバルのabcの999を表示
関数内のglobalを忘れると、分かりにくいエラーになることがあります。
abc=123 # 関数の外側で宣言した変数で、グローバルスコープ
def disp():
   print( abc ) # グローバルのabcの123したい!けどエラー
   abc = 999 #この行がなければ、上記が可能

disp()
上記の場合、「UnboundLocalError: local variable 'abc' referenced before assignment」のエラーです。
「abc = 999」あると、abcの変数はローカル変数になる。すると、設定していない変数を表示しているエラーになってしまいます。

リスト内包

リストを生成する簡潔な表記で、列挙、イテレータがベースになっている。比較するためリスト内包を使わないスタイルを以下に示す。
lst = []
for x in range(10):
   lst.append(x*2)

上記と同等のリスト内包を使った表記を示す。
lst=[ x*2 for x in range(10) ]
lst # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] の表示
上記と同等で、ラムダ式を使った表記を示す。
lst=list( map(lambda x: x*2, range(10)) )
lst # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] の表示
条件も使った例です。
z=[4,1,6,8,5]
y=[x*2 for x in z if x%2==0 ] # リスト内要素で偶数のだけを2倍にしたリストを取り出す
print(y) # [8, 12, 16 ]を表示
forの2重に使った例です。
a=[(a,b) for a in [1,2,3] for b in [9,8]]
print(a) # [(1, 9), (1, 8), (2, 9), (2, 8), (3, 9), (3, 8)] を表示
a=[X for n in range(4) for X in [1,2,3,4]]
print(a) # [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]を表示
a=[X for X in [1,2,3,4] for n in range(4)]
print(a) # [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]を表示

クラス定義

>>> class Man:
...    def __init__(self, name):
...       self.name= name
...       print ("initialized!" )
...    def hello(self):
...      print ( 'Hello ' + self.name + '!' )
...    def __str__(self):
...      return '名前は' + self.name + 'です。\n'
...
>>> m= Man("Yamada")
initialized!
>>> type(m)
<class '__main__.Man'>
>>> m.hello()
Hello Yamada!
>>> m
<__main__.Man object at 0xa325f0>
>>> print(m)
名前はYamadaです。

>>>
class Man:
   def __init__(self, name):
      self.name= name
      print ("initialized!" )
   def hello(self):
      print ( 'Hello ' + self.name + '!' )
   def __str__(self):
      return '名前は' + self.name + 'はです。\n'

m= Man("Yamada") # コンストラクタの実行でオブジェクトが生成(他の言語にあるような new演算しは存在しないし、使う仕様でない)
type(m)
m.hello()
プロンプトで、単に m を入力した時の結果は、<__main__.Man object at 0xa325f0> ですが、
print(m)を使って出力した時の結果は、「名前はYamadaです。」になっています。
これは、print関数が、引数のオブジェクトの__str__関数の戻り値を表示に使っているからです。


なお、printは次のようにファイル操作でも使われます。(encoding="shift_jis"は省略可能)
fw = open('test.txt', 'w', encoding="shift_jis")
print('hello\nてすと', file=fw) #  test.txtに出力 
fw.close()
import sys
print('hello', file=sys.stdout) #  標準出力に出力
print('hello', file=sys.stderr) #  標準エラー出力に出力
fr = open('test.txt', 'r')
print(fr.read() ) # 'hello\nてすと'が表示
fr.close()
print ( type(fr ) ) # 「<class '_io.TextIOWrapper'>」が表示

with構文

with構文は、クラス機能の利用者が、より安全で簡単にその機能を使えるようにする構文です。
with構文で使えるクラスには、「__enter__(self)」と「__exit__(self, exception_type, exception_value, traceback)」の メソッドが実装され、with実行で、呼び出される仕組みです。
これにより、ファイル操作クラス('_io.TextIOWrapper')などでは、 withを使えばclose()メソッドの呼び出し記述を書かなくても、適切に呼び出してくれます。
上記で、ファイル書き込みや読み込み操作例を紹介しているが、それをwith使用版を示します。
with open('test.txt', 'w') as fw:
   fw.write('hello')
   fw.write('てすと')

with open('test.txt', 'r') as fr:
   data = fr.read() # 全てを読む
print(data)
なお、一行づつ読む処理の例を下に示す。
data = '';
with open('test.txt', 'r') as fr:
   s = fr.readline() # 一行読み取り(改行を含めて)
   while s:
      data += s
      s = fr.readline() # 一行読み取り(改行を含めて)

print(data)

例外処理

try: と except 値: のインデントで処理を書きます( catch のキーワードはありません。)
try: と except 値:内で、「raise NameError('xx')」で送出された例外を捉えて、対応するexcept 値:のインデントに移動します。
try … except 文には、オプションで else 節 (else clause) を設けることができます。
try:
    f = open('data.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("intへの変換失敗.")
except:
    print("予測外 error:", sys.exc_info()[0])
    import traceback
    print traceback.format_exc() # traceback.print_exc()でもよい
else: # 全く例外が送出されなかったときに実行されるコードを書く
    f.close()
「raise」命令は、例外を生成して起こす場合に使います。例を示します。
raise NotImplementedError()

外部に作成した .pyのファイルを利用する

http://python.matrix.jp/pages/tips/import.html#id2

import ○○   ○○モジュール名を指定して変数や関数を使えるする。(変数変更は可)

tset.py の内容
abc=789
def get_data():
  return abc
このtset.py内変数abcや関数をを他のモジュールから使う場合、まずimportでそのモジュール名(拡張子無し)を指定しします。
そして次のように、モジュール名(拡張子無し)の記述にドットを付けて変数名を指定します。
import test
print( test.abc ) # 789 の表示
print( test.get_data() ) # 789 の表示
test.abc=123 #  他のモジュール(test.py)の変数変更も可能
print( test.get_data() )  # 123 の表示
def xxx():
   test.abc=999

xxx()
print( test.get_data() ) # 999 の表示
コメントが表示内容です。 2行目を「print( abc )」と書くと、「NameError: name 'abc' is not defined」のエラーです。

なお、import A as Bという表現のas 別名を名づけするためのものです。次のように使います。
import test as tt
print( tt.abc ) # 789 の表示
print( tt.get_data() ) # 789 の表示
なおimport A.Bという記述もあり(毎回A.Bの表現が必要)が、Aがパッケージの場合です。
よって、1行目を「import test.abc」と書くと、「ModuleNotFoundError: No module named 'test.abc'; 'test' is not a package」のエラーです。

from ○○ import □,□   ○○モジュール名を指定しなくても□変数や□関数を使えるする。(変数変更は不可)

from A import BのAでパッケージやモジュール名を指定し、
 Bでパッケージやモジュール名、クラス、関数名、変数名を指定することでBを使えるようにする記述です。
Bの箇所は、コンマで名前区切る事ができます。
以下は test.py のファイル名で以下のファイルを作った場合の例です。(UTF-8のキャラセットでファイルを保存)
# coding: UTF-8
abc=789
def get_data():
  return abc
このtest.py ファイル内のabc,get_dataを利用する準備の記述は次のようになります。
from test import abc,get_data
print( abc ) # 789 の表示
print( get_data() ) # 789 の表示
2行目を「print( test.abc )」と書くと 「NameError: name 'test' is not defined」のエラーです。
(import testをしていないので、test の名前は使えません)

なお、1行目を「from test import *」に変更しても動作可能です。
from A import *でA内の定義すべてを現時点の名前空間に上書きします。
個人的に*を使わないで「利用する名前を全て列挙すること推奨します。

なおこれは、tset.pyファイルが、同じディレクトリにある場合です。
利用するファイルが異なるディレクトリにある場合は、そのimportで検索できるディレクトリを追加する必要があります。
下記は、親ディレクトリにimportするファイルがある場合の例です。
import sys, os
sys.path.append(os.pardir) #親ディレクトリのインポートを可能に
from tset import abc,get_data
print( abc ) # 789 の表示
print( get_data() ) # 789 の表示
(testの変数abcは、この指定で参照できるようになりますが、変更することはできません
他のモジュール内変数の変更例を次でも示します。 )

import □□ と from ○○ import □□を使った例

次のような test.py があるとします。
SIZE=10

def print_SIZE():
    print(SIZE)
上記のSIZEを変更と、print_SIZE()を使う簡単な例を以下に示します。
import test
from test import print_SIZE

def set_SIZE(v):
   test.SIZE = v # 変更「import test」が必要

print(test.SIZE) # 10が表示 これは「import test」が必要

set_SIZE(555) # 555へ変更

print_SIZE() # 555の表示 これはfrom test import print_SIZE」が必要

親ディレクトリに置いたモジュールを取り込む

親ディレクトリに「utils.py」が置いてあり、その中の関数を使う場合、 次のように、「sys.path.append関数」で、 ライブラリ読み込み対象ディレクトリを追加します。
import sys
sys.path.append('..') # 親ディレクトリのモージュールを利用
import utils

なお、Python でライブラリを読み込むディレクトリは sys.path のリスト中に存在する。
よって、「print(sys.path)」の実行で確認できます。


再利用モジュールのテスト用コード

例 次のdistance.pyがあるとします。
rate=1.555
def euclid(a,b):#2 点間の距離
    r=(a[0]-b[0])**2
    r+=(a[1]-b[1])**2
    return r**0.5

class Rect:
    def __init__(self,x,y,w,h):
        self.left=x
        self.top=y
        self.width=w
        self.height=h

if __name__ == '__main__':
    print(rate) # ここでモジュールをテストする。
__name__ の表現は、モジュールのファイル名が記憶されのですが、自身のファイルが起動で使われた時だけ'__main__'の文字列が記憶されます。
自身のファイルが起動で使われない場合は、単純に自身のファイル名が記憶されます。
よって、上記の最後のif判定による実行は 、モジュール単体実行の場合だけ行われ、fromやimportで取り込んだ時は実行しない。
「from distance」や「import distance」を複数回、なんど列挙しても distance.pyのモジュールの取り込み実行は1回だけです。