ざっとPython3 の初歩

Pythonの文法を一通り眺めるためのページです.
C言語などを授業などでなんとなく学習したつもりの人向けです.
そうでない人でも,サンプルのソースコードを打ち込んでその動作を見れば,なんとなく雰囲気はわかるでしょう.

開発環境のインストールがまだの場合は,こちらを参照してください.

開発環境のテスト

Pythonはインタプリタ言語なので,プログラムを1行づつ入力することができる.
(以下の赤字の部分を順次入力し,Enterキーを押す.)

>>> print('Hello world!')
Hello world!
>>> i=5+3
>>> print('i=', i)
i= 8
>>>

このように,インタプリタ言語では,電卓のように簡単に計算プログラムを書くことができる.

処理手順が長くなると入力するのが面倒で,間違いも多くなるので,あらかじめソースファイルを書いて保存しておき,一度に実行することもできる.

# 以下を test.py として保存

print(' --- Calc. prog. ---')
i = 3 + 5
j = 4 * 5
print('ans = ', i * j)
(実行方法)
Z:\> python test.py
 --- Calc. prog. ---
ans =  160

このように,どちらの方法でもプログラムを実行することが可能である.

  1. インタラクティブモードで実行.コマンドラインからpython(Macではpython3)と打ち込んで,>>> のプロンプトで 1 行ごとに実行.
  2. ソースファイル(test.py など,拡張子はpy)に記述・保存し,コマンドラインまたはシェルから python test.py(Macではpython3 test.py) とする.

ちょっとしたテストなら1,何度も繰り返すような処理なら2で実行するとよい.

そのほか,Pythonをインストールすると同時にインストールされるIDLEエディタを使用すると,F5キー(Windowsの場合)で,すぐに実行結果が確認できるので便利.

画面出力の基本

コンソール出力

print('Hello World!')
print('This is a "pen".')
実行結果
Hello World!
This is a "pen".

これだけでよい.

文字列の括りは,"でも ' でもOK.
互いに表示したいときにいちいちエスケープしなくてもよいので便利.

print では改行が勝手に追加されるので,抑止したければ,end を空に指定する.
逆に,endに文字列を設定すると,文字列の最後に毎度毎度追加される.

print('ABC', end='')    # ''は,シングルクオーテーション2つ
print('XYZ')

print('123', end='---')
print('456')
出力:
ABCXYZ
123---456

print では複数の値や変数をカンマ区切りで連続して出力できる.
たとえば,変数の値を表示したければ,

i = 100
j = 200.5
print('Hello World! i=', i, ' j=', j)
出力:
Hello World! i= 100  j= 200.5

このとき,文字列と数値の間にスペースが自動的に(勝手に?)入る.
区切り文字変更するときは sep 変数を指定.

print(100, 200, 300)
print(100, 200, 300, sep = '')     # ''は,シングルクオーテーション2つ
print(100, 200, 300, sep = ',')
print(100, 200, 300, sep = '----')
print(100, 200, 300, sep = ' | ')
出力:
100 200 300
100200300
100,200,300
100----200----300
100 | 200 | 300

変数は,数値だけでなく文字列もOK.

i = 'OMG!'
print('Hello World! i =', i)
print(i)                # OK
print(i + ' --- ' + i)  # 文字列の連結, OK
print(i + '1' )         # OK
print(i + 1)            # これはERROR !. i は文字なので,数値を足せない
出力
Hello World! i = OMG!
OMG!
OMG! --- OMG!
OMG!1
Traceback (most recent call last):
  File "/Users/tatsuya/Desktop/test.py", line 6, in <module>
    print(i + 1)            # これはNG. i は文字なので,数値を足せない
TypeError: can only concatenate str (not "int") to str

書式指定出力

format

C言語の printf 風の書式指定が使いたい場合

name = 'Paul'
age = 90

print('%s is %04d years old.' % (name, age))
出力:
Paul is 0090 years old.

異なる基数の整数

d = -10     # 10進数
h = 0x20    # 16進数
o = 0o77    #  8進数
b = 0b1010  #  2進数

print('10進数:d=%d h=%d o=%d b=%d' % (d,h,o,b))
print('16進数:d=%x h=%x o=%x b=%x' % (d,h,o,b))
print(' 8進数:d=%o h=%o o=%o b=%o' % (d,h,o,b))
出力:
10進数:d=-10 h=32 o=63 b=10
16進数:d=-a h=20 o=3f b=a
 8進数:d=-12 h=40 o=77 b=12

2進数の表示はどうやるんだろう.

浮動小数の桁指定,指数表示

pi = 3.14159265358979
print('pi=%f' % pi)
print('pi=%.15f' % pi)

print('pi=%e' % pi)
print('pi=%.15e' % pi)
出力:
pi=3.141593
pi=3.141592653589790
pi=3.141593e+00
pi=3.141592653589790e+00

デフォルトで,表示される桁数で自動的に四捨五入される模様.

キーボード入力

C言語でいう scanf() に相当.

ret = input('Input a number:')

scanfと違って,input の引数に,入力メッセージを渡すことができるので,便利.

重要:キーボードからの入力は,文字列として返され,ここでは,変数 ret に代入される.

str1 = input('input a number 1:')
str2 = input('input a number 2:')

sum = str1 + str2
print(sum)
出力:
input a number 1:10
input a number 2:20
1020

このように,(予想した?) 30 ではなく,1020 と表示される.
これは,千と二十ではなく,イチ・ゼロ・ニ・ゼロ が表示されている.

数値として計算したい場合は,int(), float()を使って,数値に変換する. (Cでいうところの atoi, atof, strtol, strtof

str1 = input('input a number 1:')
str2 = input('input a number 2:')

sum = int(str1) + int(str2)
print(sum)
出力:
input a number 1:10
input a number 2:20
30

あるいは,最初から数値に変換して変数に代入.
(変数名をx,yに変えてある.)

x = int ( input('input a number 1:') )
y = int ( input('input a number 2:') )

sum = x + y
print(sum)

逆に,数値を文字列にする場合は,str(数値) を使う.

変数の型

変数の型 == クラスと考えて差し支えない.
型は動的に決まるので,宣言時に型名で悩まなくてもよい.

# こんなのもOK.

i = 10
print(i)
i = 'Hello'
print(i)
実行結果
10
Hello

変数の型を調べるには,type() を使う.

# 対話モードなら,printは不要.

print( type(10) )
print( type(10.0) )
print( type("10") )
print( type('10') )
実行結果
<class 'int'>
<class 'float'>
<class 'str'>
<class 'str'>

四則演算

+, -, *, /, //, %, **

割り算は,Python 2 と Python 3 で異なる!
C言語とも少し違うので要注意.

**は便利.

print(12 + 5)
print(12 - 5)
print(12 * 5)

print(12 / 5)     # 浮動小数.C言語と違う!
print(12 // 5)    # 整数で割り算.小数点以下は切り捨て

print(12 % 5)

print(12 ** 5)    # べき乗
実行結果
17
7
60
2.4
2
2
248832

条件分岐

関係(比較)演算子

数値(や文字コード)の大小を比較する演算子.Cと同じ.
式全体として,TrueFalseのいずれかの値をとる.

<, > <=, >=, ==, !=

print(2 > 3)
print(2 < 3)
実行結果
False
True

論理演算子

and, or, not
C言語では,&& || !
Pythonの方が直接的でわかりやすいかも.

print(True and False)
print(False and False)

print(True or True)
print(True or False)
print(False or False)

print(not True)

print('---------------')

p = ( 1 > 2 )  # False
q = ( 1 < 2 )  # True
print(p and q)
print(p or q)
print(not p)
実行結果:
False
False
True
True
False
False
---------------
False
True
True

if

i = int(input('i=?'))

if i > 0:
    print('正です.')
elif i < 0:
    print('負です.')
else:
    print('ゼロです.')

print('おわり.')
実行結果
i=? 10
正です.

elif:else: は,不要な場合はカットできる.

pythonでは,コードブロックを字下げで表すので,正しく字下げしないとエラーになる!
試しに,いずれかのprint 文のインデントを削除して左づめにしてみよう.速攻でエラーが出るはず.
(C言語では,{}で括られていれば,字下げありでもなしでもOK)

Pythonにとってインデントは,ソースコードの見た目の良し悪しの問題ではなく, 綺麗に書かないとプログラムが正しく実行できないという素晴らしい言語仕様となっている.

繰り返し

while

字下げ重要.

i=0
while i<=10:
   print(i)
   i+=1       # 残念ながら,i++ はエラー!

for

数値の連番の反復には,rangeを使用.
range(n) で,0,1,2, ... , n-1 までの値.

for i in range(5):
   print(i)
実行結果
0
1
2
3
4

rangeは,(初期値, 終了値, 増加させる値)と書くことができる.

for i in range(20, 10, -2):
   print(i)
実行結果
20
18
16
14
12

終了値には到達しないので注意!

リストを渡せる.

array = [1, 3, 5, 10]   # リスト
for i in array:
    print(i)
実行結果
1
3
5
10

なんと,数値だけでなく,文字列が混在してもOK

array = ['Oh', 'My', 'goodness', 10, 20]   # 混在リスト
for i in array:
    print(i)
実行結果
Oh
My
goodness
10
20

print(i, type(i)) と変更して,データの種類を確認しよう.

実行結果
Oh <class 'str'>
My <class 'str'>
goodness <class 'str'>
10 <class 'int'>
20 <class 'int'>

break

ループ途中でbreakすると,そのループを脱出.
C言語と同じ.

i=0
while i<=10:
   print(i)
   if i == 5:
      print('break!')
      break;
   i=i+1
   
print('finish.')

continue

ループ途中で,その回の処理をスキップして次の反復へ進む.
C言語と同じ.

for i in range(10):
   if i%2 == 0:
      print('continue!')
      continue;
   print(i)
   
print('finish.')

関数

pythonでは,関数のコードブロックを字下げで表すので,字下げしないとエラーになる! (C言語では,{}で括られていれば,字下げなしでもOK)
言い換えると,見た目の問題ではなく,ソースコードのインデントを綺麗に書かないとプログラムが正しく実行できないという素晴らしい言語仕様である.

def func():
   print('Hello!')    # 字下げ重要

func()
func()
func()
実行結果
Hello!
Hello!
Hello!

パラメータ(つまり引数)の渡し方

順に渡す.型名は不要.

def func(a, b):
   print('a=', a, 'b=', b)

func(1, 2)
func(3.2, 4.9)
func('AAA', 'ZZZ')
実行結果
a= 1 b= 2
a= 3.2 b= 4.9
a= AAA b= ZZZ

仮引数は,いわゆる値参照?
関数内で引数を変更しても,呼び出し元には影響しない.

def func(a):
   a=100

a=1
print('a=', a)
func(a)
print('a=', a)
実行結果
a= 1
a= 1

関数にリストを渡すのもOK.

def func(a):
    print('a=', a)
   
a = [1,2,3]
func(a)

実行結果
a = [1, 2, 3]

リスト

リストは,C言語でいう配列のようなものであるが,Pythonでは色々な型を混在できる
このような「変数をまとめて扱う機能」は,一般に「コンテナ」と呼ばれる.

普通の変数と同様,宣言時に型を指定する必要もない.
宣言には角かっこ [ ] を用い,要素をカンマ区切りで書く.
添字は C と同様,オフセット0が先頭.

a = [10, 20, 30]
print('a =', a)
print('a[0] =', a[0])
print('a[1] =', a[1])
print('a[2] =', a[2])
実行結果
a =  [10, 20, 30]
a[0] =  10
a[1] =  20
a[2] =  30

各要素は書き換え可能.

a = [10, 20, 30]
print('a =', a)
a[0] = 100
print('a =', a)
実行結果
a =  [10, 20, 30]
a =  [100, 20, 30]

負の添字で,配列最後からアクセスできる.

a = [10, 20, 30]
print('a = ', a)
print('a[-1] =', a[-1])
print('a[-2] =', a[-2])
print('a[-3] =', a[-3])
実行結果
a = [10, 20, 30]
a[-1] = 30
a[-2] = 20
a[-3] = 10

境界をはみ出ると...

a = [10, 20, 30]
print('a =', a)
print('a[0] =', a[0])  # OK
print('a[1] =', a[1])  # OK
print('a[2] =', a[2])  # ここまではOK
print('a[3] =', a[3])  # ???
print('a[4] =', a[4])  # OMG!
実行結果
a = [10, 20, 30]
a[0] = 10
a[1] = 20
a[2] = 30
Traceback (most recent call last):
  File "/Users/tatsuya/Desktop/test.py", line 6, in <module>
    print('a[3] =', a[3])  # ???
IndexError: list index out of range

のように,きちんとエラーが出る.
C言語の配列だと,なんとなく実行できてしまうので怖いが,こっちの方がGood.
しかし,(おそらく)処理速度が犠牲になっている.

リストの中身は数値でなくても良い.(文字列の配列は,Cだと「ポインタの配列」が必要)
リストの型名は type() で得られる.

a = ['Oh', 'My', 'Goodness']
print('a = ', a)
print('a[0] =', a[0])
print('a[1] =', a[1])
print('a[2] =', a[2])
print(type(a))
print(type(a[0]))
print(type(a[0][0]))
実行結果
a =  ['Oh', 'My', 'Goodness']
a[0] = Oh
a[1] = My
a[2] = Goodness
<class 'list'>
<class 'str'>
<class 'str'>

リストの中身は数値と文字が混在しても良い. リストのサイズ(=要素数)は len() で得られる.

a = ['Oh', 10, 'My', 20, 'Goodness']
print('a = ', a)
print('len(a) = ', len(a) )

print('a[0] =', a[0])
print('a[1] =', a[1])
print('a[2] =', a[2])
print('a[3] =', a[3])
print('a[4] =', a[4])
実行結果
a =  ['Oh', 10, 'My', 20, 'Goodness']
len(a) =  5
a[0] = Oh
a[1] = 10
a[2] = My
a[3] = 20
a[4] = Goodness

リストを使った繰り返し文

prime = [2, 3, 5, 7, 11, 13, 17, 19]   # リスト

for i in prime:        # リストを使った繰り返し文
   print(i, end=',')

数値と文字が混在したリストでもOK.(何に使うんだろう)

array = ['Oh', 'My', 'goodness', 10, 20]   # 混在リスト

for i in array:
   print(i)
実行結果
Oh
My
goodness
10
20

ファイル入出力

ファイル出力

f = open('sample.txt', 'w')
f.write('Hello World!\nGood Bye!')
f.close()

ファイル名などは,変数を使おう.

fname = 'sample.txt'
f = open(fname, 'w')

data = 'Hello World!\nGood Bye!'
f.write(data)

f.close()

ファイル入力

基本

f = open('sample.txt', 'r')
line = f.readline()        # (改行コードも含め)1行読み込み
print(line)
f.close()

これだと1行しか読み込まれないので,

f = open('sample.txt', 'r')
for line in f:
   print(line)
f.close()
実行結果
Hello World!

Good Bye!

print で表示すると,改行コードが余分に入るため,1行空行ができる.

全行をリストに読み込む方法

これだと,読み込みと処理を分離できるが,ファイルがとても巨大な場合にどうなるんだろうか.

f = open('sample.txt', 'r')
lines = f.readlines() 
f.close()

print(lines)
実行結果
['Hello World!\n', 'Good Bye!']

エラー処理

ファイル処理は,なんだかんだエラーが発生する.

書き込むファイルが他のアプリでロックされている.
読み込むファイルが存在しない.など.

エラー処理には,「例外処理」を使用する.詳しい説明はここでは省略.

fname = 'non-existing-file.txt'

try:
   f = open(fname, 'r')
   lines = f.readlines() 

except:
   print('読み込めなーい')

else:
   print('読み込みました.')
   print(lines)
   f.close()

finally:
   print('おしまい.')
実行結果:
読み込めなーい
おしまい.

例外処理

ゼロ割り算とか,ファイル入出力とか,エラー発生時にすべき処理.
(最初から想定されるエラーは,あらかじめif文などで対応しておく. それ以外の,実際に実行してみないと発生するかどうかわからないエラーへの対応.)

例外処理なし.

f = 1/0        # え!?

実行結果:
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    f = 1/0
ZeroDivisionError: division by zero

例外処理あり.

try:
    print('計算します.')
    f = 1/0              # ん?

except:
    print('なにかえらー!')

else:
    print('うまくいった.')

finally:
    print('おわったよ.')
実行結果:
計算します.
なにかえらー!
おわったよ.

例外処理をうまく記述すれば,エラー発生時にTracebackで強制的に中断されることなく,処理を続行させるか中止するかを制御できる.

ファイルシステム関連

指定したディレクトリ内のファイル名を探索

import os

try:
    path = './'
    dir = os.listdir(path)
    print(dir)

    files = [f for f in dir if os.path.isfile(os.path.join(path, f))]   # ディレクトリを除く
    print(files)    # list で表示

    for f in files:    # 1行ごとに表示
        print(f)
except:
    print('エラー')

GUI

Windowが開くだけです.

拡張子はpyw.とする. test.pyw など.
(.pyでも良い)

import tkinter

class MainWindow(tkinter.Frame):
   def __init__(self, parent):
      super(MainWindow, self).__init__(parent)
      self.parent = parent

   def quit(self, event=None):
      self.parent.destroy()

application = tkinter.Tk()
application.title('Example')
window = MainWindow(application)
application.protocol('WM_DELETE_WINDOW', window.quit)
application.mainloop()

Windowが開くはず.(ウインドウの後ろに隠れて現れるかも.)

発展的内容

ここではこれ以上詳しい説明は行わないが,これ以外にも多くの役立つトピックがある.
興味がある諸君は積極的に自分で調べて学習してみよう.

真っ先に使いそうなライブラリ

機械学習で使われるもの