jupyter notebook --no-browserでJupyterを起動しておき(こうするとブラウザが自動で開いたりはしない)、FirefoxやChromeのようなお好みのブラウザを立ち上げてから、
import thisを実行すると次のメッセージが表示される。これがプログラミング言語Pythonの哲学を表している:
The Zen of Python, by Tim Peters Beautiful is better than ugly. # 醜いよりも美しい方が良い Explicit is better than implicit. # 暗黙的になっているよりも明示されている方が良い Simple is better than complex. # 複雑なものよりも単純な方が良い Complex is better than complicated. # 混乱しているよりは複雑な方が良い Flat is better than nested. # 入れ子になっているよりも平坦な方が良い Sparse is better than dense. # 固まっているよりもまばらな方が良い Readability counts. # 読みやすさが大事 Special cases aren't special enough to break the rules. # 原則を破るような特例があるのはおかしい Although practicality beats purity. # もっとも,純粋さよりも実用が勝つのではあるが。 Errors should never pass silently. # エラーを黙って見逃してはならない Unless explicitly silenced. # ただし、黙れと命令されない限り。 In the face of ambiguity, refuse the temptation to guess. # 曖昧さに直面したら、推測するのはやめよう There should be one-- and preferably only one --obvious way to do it. # 何かをするには明らかな方法が一つ、できればただ一つだけあるべき Although that way may not be obvious at first unless you're Dutch. # もっとも最初はそうは見えないかもしれないが Now is better than never. # やらないよりは、今やったほうが良い Although never is often better than *right* now. # もっとも「今すぐ」やるよりは、やらないほうが良いことも多い If the implementation is hard to explain, it's a bad idea. # 実装方法が説明しづらいものなら、それは良くない方法だ If the implementation is easy to explain, it may be a good idea. # 実装方法が説明しやすければ、それはよい方法の可能性あり Namespaces are one honking great idea -- let's do more of those! # 名前空間はよいアイデアだ、たくさん作ろう
def trial( ): # 関数trial のブロックの始まり for i in range(5): # for i 文のブロックの始まり print(i) # for i 文のブロックの最初の行 for j in range(5): # for j 文のブロックの始まり print(j) # for j 文のブロックの最初の行 print(i*j) # for j 文のブロックの最後の行 print(i) # for i 文のブロックの最後の行 print("owari") # 関数trialのブロックの最後の行同じブロック内にあるコードは、きっちり同じだけの(半角)空白が行の先頭にないとエラーになるので注意深くなろう。 特に、空行には注意しよう。次のコードには関数の定義の途中に改行がはいっているが、この行も関数trial2のブロックの一部として、適切な数だけの空白が必要なのである。それがなければ、Pythonはtiral2の関数定義が終わったものとみなしてしまう(ため、次の行に対してIndentationErrorというエラーを起こす)。
def trial2(x, y): z = x*y print(z)
丸括弧と角括弧の内部では、空白は無視されるので、長い行を折り返して書くことができる。そのためコードを読みやすく書ける:
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
import cv2次はrandomモジュールで定義されているrandom関数の使用例である。
import random x = random.random() print(x)randomモジュールは乱数を扱うモジュールで、指定した区間で整数乱数を返す randint関数などが定義されている。 ここでは[0, 1)区間の一様乱数を返す random関数を使用したが、このようにモジュール名と関数名とはドット(.)で接合する必要がある。 しかし、ここでもしもrandomモジュールのうちrandom関数しか使わないのであれば、次のようにしてその関数だけを取り込むことができる。
from random import random x = random() print(x)なおモジュール名にはとても長いものがある。そういう時には別名(要するにニックネーム)を使う。以下ではPythonで一般的に用いられるモジュールとその別名である:
import numpy as np # 数値計算ライブラリ import pandas as pd # データ変換・解析ライブラリ import scipy as sp # 科学技術計算のライブラリ import scipy.stats as st # 統計のライブラリ import matplotlib.pyplot as plt # グラフ描画ライブラリ。matplotlibモジュールのpyplotライブラリだけをimportしている
ほとんどの言語と同じく、Pythonには、整数、浮動小数点数、ブール値、文字列などの多くの基本のデータ型があります。これらのデータ型は、他のプログラミング言語と同じ様に動きます。
x = 3
print( x, type(x) ) # xの値とデータ型の表示
print( x + 1 ) # Addition; 足し算
print( x - 1 ) # Subtraction; 引き算
print( x * 2 ) # Multiplication; 掛け算
print( x ** 2 ) # Exponentiation; 乗数
print( x // 2 ) # Division: 割り算。ただし結果は整数
print( x / 2 ) # Division: 割り算。ただし結果は浮動小数点数
x += 1
print( x ) # x = x+1 と同じ
x *= 2
print( x ) # x = x*2 と同じ
x -= 3
x **= 2
x %= 7
x //= 3
x /= 3
は何と同じであろうか、類推してみよう。また実際に確かめてみよう。
# 確かめてみよう
y = 2.5
print( type(y) ) # "<type 'float'>" と出力
print( y, y + 1, y * 2, y ** 2 ) # "2.5 3.5 5.0 6.25"と出力
C言語とは異なり、Pythonには単項インクリメント(x++
)やデクリメント(x--
)演算子がないことに注意しよう。
Pythonでは、長い整数と複素数を組み込みで扱うことができます。これについての詳細は ドキュメントをご覧ください。
Pythonはブール論理の通常の演算子のすべてを実装していますが、&&
、||
のような記号ではなく、and
やor
というように英語の単語を使用します
t, f = True, False
print( type(t) ) # Prints "<type 'bool'>"
論理演算をすべて使ってみましょう
print( t and f ) # AND : 論理積
print( t or f ) # OR : 論理和
print( not t ) # NOT : 否定
print( t != f ) # XOR : 排他的論理和
Pythonには文字列に対する素晴らしいサポートがあります
hello = 'hello' # 文字列を示すには、一重引用符でも
world = "world" # 二重引用符でも、どちらも使える
print( hello, len(hello), type(world) )
hw = hello + ' ' + world # 文字列の結合
print( hw ) # "hello world"と出力
hw12 = '%s %s %d' % (hello, world, 12) # sprintf 流の文字列生成
print( hw12 ) # "hello world 12"と出力
Stringオブジェクトには便利なメソッドがたくさんあります。次はその例:
s = "hello"
print (s.capitalize() ) # 文字列をキャピタライズ(先頭のみ大文字); "Hello"と出力
print (s.upper() ) # 文字列を大文字に変換; "HELLO"と出力
print (s.rjust(9) ) # 文字列を右揃え(左にスペースを入れる); " hello"と出力
print (s.center(9) ) # 文字列を中央寄せ(左右にスペースを入れる); " hello "と出力
print (s.ljust(9) ) # 文字列を左揃え(右にスペースを入れる); "hello "と出力
print (s.replace('l', '(ell)') ) # すべてのlを(ell)で置き換える; "he(ell)(ell)o"と出力
print ('\t world \n'.strip() ) # 先頭と末尾の空白文字を切り落とす; "world"と出力
C言語を知っている人には意外に思うかもしれませんが、文字列内容の比較も演算子を用いて行えます:
str = 'Jane'
print(str =='Jane')
print('abc' < 'def')
print('def' >= 'abc')
すべての文字列メソッドのリストについて知りたければドキュメントをご覧ください。
xs = [3, 1, 2] # リストを作る
print (xs, xs[2])
print (xs[-1] ) # 負のインデックスは後ろから数えることを意味する。だから "2" を表示する
xs[2] = 'foo' # リストはいろいろな型の要素をもつことができる
print (xs)
xs.append('bar') # リストの最後に新しい要素を付け加える
print (xs)
print(xs+[0,'baz']) # リスト同士を結合
print(xs) # とはいっても元のxsには変更なし
x = xs.pop() # リストの最後から要素を取り除き、その要素を返す
print (x, xs)
今までと同様に、リストについての詳細は ドキュメント でみることができます。
リストの要素一つ一つにアクセスするのに加えて、Pythonはサブリスト(リストの一部分)にアクセスする手段を提供しています。これはスライスとして知られてます。
nums = list(range(5)) # range で指定された範囲の整数からなるリストをlistで作る。どちらも組み込みの関数
print (nums ) # "[0, 1, 2, 3, 4]"と出力
print (nums[2:4]) # 2 番目から 4 番目までの要素(4番目の要素は含まない)からなるスライス: "[2, 3]"と出力
print (nums[2:]) # 2番目 から最後の要素からなるスライス; "[2, 3, 4]"と出力
print (nums[:2]) # 先頭から2番目までの要素(2番目の要素は含まない) からなるスライス: "[0, 1]"と出力
print (nums[:]) # 全部の要素からなるスライス: ["0, 1, 2, 3, 4]"と出力
print (nums[:-1] ) # スライスのインデックス指定にも負の数が使える: ["0, 1, 2, 3]"と出力
nums[2:4] = [8, 9] # 新しい要素で num[2:4]のスライスの部分を置換
print (nums) # "[0, 1, 8, 9, 4]"と出力
このようなリストの要素を繰り返し(ループ)で使用することができます。次のfor文では、繰り返しごとにanimaslリストの一つ一つの要素がanimalの値となり、print文が実行されます。このようにfor文の基本構造は次のとおりです:
for 変数 in リスト(コンテナ): 繰り返されるコード
animals = ['cat', 'dog', 'monkey']
for animal in animals:
print (animal)
ループの本体で要素のインデックスにアクセスしたい場合は、組み込みのenumerate
機能を使用します:
animals = ['cat', 'dog', 'monkey']
for idx, animal in enumerate(animals):
print( '#%d: %s' % (idx + 1, animal) )
プログラミングではよく、データ変換したくなることがあります。その簡単な例として、次のような二乗を計算するコードを考えてみましょう。
nums = [0, 1, 2, 3, 4]
squares = []
for x in nums:
squares.append(x ** 2)
print(squares)
このようなコードは、リストの内包記法を使って簡単に書くことができます:
nums = [0, 1, 2, 3, 4]
squares = [x ** 2 for x in nums]
print (squares)
このようにリスト内包記法の基本形は以下です:
[ 式 for 変数 in リスト(コンテナ)]
これによってリストの要素それぞれが変数の値となり、その変数の値を使って「式」が計算され、その結果すべてを集めたリストが結果となります
リスト内包表記には条件も含めることができます:
[ 式 for 変数 in リスト(コンテナ) if 条件]
なお、「式」にはif文(後述)も書けます:
[ 式 if 条件 else 式 for 変数 in リスト(コンテナ) ]
nums = [0, 1, 2, 3, 4]
even_squares = [x ** 2 for x in nums if x % 2 == 0]
print (even_squares)
print([True if x % 2 == 0 else False for x in nums]) # 偶数ならTrue, 奇数ならFalseからなるリストに変換
なお、繰り返しに「多重繰り返し」があるように、リスト内包記法にも次の例のように繰り返しの部分を多重にすることができます:
print(['%s loves %s'%(x,y) for x in ['Mary','Jane'] for y in ['Tom', 'John', 'Fred']])
辞書とは
JavaのMap
やJavaScriptのオブジェクトと同じく、
(キー、値)というペアを記録するものです。これは次のように使用できます:
d = {'cat': 'cute', 'dog': 'furry'} # いくつかのデータを持つ辞書を作る
print (d['cat']) # 辞書から項目を取り出す; "cute"と出力する
print ('cat' in d) # 辞書に指定されたキーがあるかどうか調べる; "True"と出力する
d['fish'] = 'wet' # 辞書に新たな項目を記憶させる
print (d['fish'] ) # "wet"と出力する
print (d['monkey']) # KeyError: 'monkey'は辞書dの項目にはないためエラーになる
print (d.get('monkey', 'N/A')) # default値をつけて項目にアクセス; "N/A"と出力する
print (d.get('fish', 'N/A')) # default値をつけて項目にアクセス; "wet"と出力する
del d['fish'] # 辞書dから項目を削除
print (d.get('fish', 'N/A')) # "fish" はもはやや辞書dには登録されていない: "N/A"と出力する
d = {'person': 2, 'cat': 4, 'spider': 8}
for animal in d:
legs = d[animal]
print ('A %s has %d legs' % (animal, legs))
キーとそれに対応する値にいっぺんにアクセスしたい場合は、items
メソッドを使います:
d = {'person': 2, 'cat': 4, 'spider': 8}
for animal,legs in d.items():
print ('A %s has %d legs' % (animal, legs))
リスト内包に似た方法で、簡単に辞書を構築することができます。その例:
nums = [0, 1, 2, 3, 4] # 同じことは nums=range(5) としてもできます
even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0}
print (even_num_to_square)
animals = {'cat', 'dog'}
print ('cat' in animals ) # 集合にある要素が含まれているかどうかチェックする; "True"と出力する
print ('fish' in animals) # "False"と出力する
animals.add('fish') # 集合に要素を付け加える
print ('fish' in animals)
print (len(animals)) # 集合の要素数を返す
animals.add('cat') # 集合にすでに要素がある場合にはなにもしない
print (len(animals) )
animals.remove('cat') # 集合から要素を取り除く
print (len(animals) )
集合の繰り返し処理は、リストの反復処理と同じ構文で行います。ただし、集合の順序は順序付けされていないため、集合の要素を参照する順番を前提にすることはできません。
animals = {'cat', 'dog', 'fish'}
for idx, animal in enumerate(animals):
print ('#%d: %s' % (idx + 1, animal))
# "#1: fish", "#2: dog", "#3: cat"と出力する
リストや辞書のように、集合の内包表記を使用して集合を作ることができます。
from math import sqrt
print ({int(sqrt(x)) for x in range(30)})
いつものように、集合についての詳細は このドキュメントをみてください。
タプルとは値の(不変の)順序付けられたリストのことです。ただしリストとの最も重要な違いの1つは、タプルを辞書のキーとしても集合の要素としても使用できるのに対し、リストはそれができないということです。簡単な例を示します:
d = {(x, x + 1): x for x in range(10)} # タプルをキーとする辞書を作る. range(10)はリスト[0,1,..,9]に相当する
print (d[(1, 2)])
t = (5, 6) # タプルを作る
print (type(t))
print (d[t] )
t[0] = 1 # タプルに新たな要素を付け加えたり削除したりはできません
このドキュメントに、タプルに関する詳細な情報があります。
if 条件 : ブロックこれは「条件」が成り立つかどうか調べ、成り立つ(真となる)場合にだけブロックを実行するものです。まずはこの例をみましょう。
import datetime
today = datetime.datetime.now()
if today.weekday() < 5:
print("Work hard!")
上ではdatetimeモジュールをimportして、今日の日付の情報をtoday変数にセットしています。today.weekday関数は曜日を数として返すもので、月曜日は0、金曜日は4, 土曜日は5, 日曜日は6となっています。ですから、この例は今日が月曜から金曜のいずれかであればWord hard(頑張って働こう)というメッセージを表示します。
もしも、今日が土曜か日曜なら、上のコードは何も表示しません。それではちょっと寂しいので、土曜か日曜の場合は Let's have a party! (パーティしよう)を表示させることにしましょう。そのためのコードが以下です。ここで else に注目してください。
if today.weekday() < 5:
print("Work hard!")
else:
print("Let's have a party!")
このようにelse文によって『条件」が成り立たなかった場合に実行するブロックを指定できます。ここでelseは対応するifと同じインデントになっていることに気をつけましょう。
さて、ここで土曜はパーティをしてもよいけど、日曜はゆっくり休みたいとしましょう。それには elif文を使います。そのためのコードが次です:
if today.weekday() < 5:
print("Work hard!")
elif today.weekday() == 5:
print("Let's have a party!")
else:
print("Take a rest.")
if文に対してelse文はひとつだけしか書けませんが、elif文はたくさん使えます。これによっていろいろな条件によって処理を細かく分けることが可能になります。またif文は入れ子にもできます。そうであってもPythonでは、どのelse文がどのif文に対応するものかわかりにくくなることはありません。そう、そのためにインデントがあるのです。インデントによってコードがどのブロックに属するものかがはっきりします。
if 条件01: 条件01が成り立った時の処理 if 条件11: 条件01が成り立ち、かつ条件11が成り立った時の処理 else: 条件01が成り立ち、かつ条件11が不成立の時の処理 elif 条件02: 条件01が不成立で条件02が成立した時の処理 elif 条件03: 条件01も条件02も不成立で条件03が成立した時の処理 elif 条件04: 条件01も条件02も条件03も不成立で条件04が成立した時の処理 else: 条件01,条件02, 条件03 条件04がすべて不成立の時の処理
for 変数 in コンテナ(リストや辞書) : ブロック(一般に複数のコード)「変数」にはコンテナの要素が一つ一つ代入され、それぞれの要素の値ごとにブロックの処理が行われます。なお、コンテナの代わりに
for x in range(5):
print("I love you!")
# I love youを5回繰り返し表示
while 条件: ブロック(一般に複数のコード)この条件は繰り返しの前にも、またブロックの処理ごとにチェックされます。そしてその条件が成り立っている間はブロックが実行され続けます。例えば、Yesという入力がもらえるまで"Marry me, please!"と表示し続けるコードは以下のように書けます:
response = "No"
while response != "Yes":
print("Marry me, please!")
response = input("? ")
while文の特殊な使い方として、永久にある処理をし続けさせるということがあります。それには「常に真」となる条件を書けばよいのです。そのための方法は次です(注意:これは本当に「停止しません」。これを止めるにはJupyterプロセスを停止させる---Ctrl-C (コントロールキーを押しておいてCを押す)が必要です。)
while True:
print("Caution: this won't stop forever!")
繰り返しの中で使えるものに break文とcontinue文があります。breakは繰り返しをその時点で終了させ、continueは繰り返しの先頭に戻らせるものです。これを使って「結婚して」の例を書き換えてみたのが以下です:
while True:
print("Marry me, please!")
response = input("? ")
if (response != "Yes"):
continue
else:
break
# end of the loop
答は「エラーが発生(してプログラムが停止)する」である。これはPythonに限らずどのプログラミング言語でも同じである。
これを『例外』という。
print(3/0)
実は例外はしばしば起こる。例えばファイルから何かを読もうとする場合、対象のファイルがなければ例外が発生する。 しかし例外が起きてもプログラムを停止させる必要はない。例外は起きたとしてもプログラムによってうまく扱うことができる。そのためにPythonではtry-except文が用意されている。
try-except文の基本形は次のとおりである。try文のブロックにエラーが起きるかもしれないコードを置く。もしもエラーが起きた時は次にあるexcept文のブロックが実行され、エラーが(運良く!)起きなければ、try-except文は終了し、その次に書かれているコードが実行される:
try: 怪しいコードを含むブロック except: エラーが起きた時の処理 # エラーが起きても起きなくても、次の処理が行われる
try:
print("example of zero division:",3/0)
except:
print("error occurred!")
print("and the process is going on...")
Pythonの関数はdef
キーワードを使用して定義されます。その例が次:
def sign(x):
if x > 0:
return 'positive'
elif x < 0:
return 'negative'
else:
return 'zero'
# 実行例
for x in [-1, 0, 1]:
print (sign(x))
次のように、オプションのキーワード引数を取る関数を定義することがよくあります:
def hello(name, loud=False):
if loud:
print ('HELLO, %s' % name.upper())
else:
print ('Hello, %s!' % name)
hello('Bob')
hello('Fred', loud=True)
class Greeter:
# Constructor
def __init__(self, name):
self.name = name # インスタンス変数を作成する
# Instance method
def greet(self, loud=False):
if loud:
print ('HELLO, %s!' % self.name.upper())
else:
print ('Hello, %s' % self.name)
g = Greeter('Fred') # Greeter クラスのインスタンスの作成
g.greet() # インスタンスメソッドを呼び出す; "Hello, Fred"と出力
g.greet(loud=True) # インスタンスメソッドを呼び出す; "HELLO, FRED!"と出力
Pythonのクラスについて このドキュメントにより、 詳しく知ることができます。
1. 数を要素とするリストを引数にとり、その総和を返す関数sumがPythonでは組み込み関数として用意されている。例えば sum([1,2,3])は6を返す。
これと同じ役割をする関数 mySum をsumを使わずに作れ。
# 問題1
2. 数を要素とするリストを引数にとり、その最大値を返す関数maxがPythonでは組み込み関数として用意されている。例えば max([1,2,3,6,4])は6を返す。
これと同じ役割をする関数 myMax をmaxを使わずに作れ。
# 問題2
3. 整数を要素とするリストを引数にとり、その中で最小の奇数を返す関数 minOdd を作れ。ただし奇数がない場合はNoneを返すものとする。またPythonの組み込み関数を使っても良いとする。
# 問題3
4. リストの要素のうち、2番めに小さな要素を返す関数 secondMin を作れ。なおこの関数の引数はリスト1個だけとする。またPythonの組み込み関数を使っても良いとする。
実行例: secondMin([2,5,7,9,1,8,4,0]) => 1
# 問題4
5. list関数は文字列を引数に取り、それを構成する文字のリストを返す組み込み関数である。
list('abc') ⇒ ['a', 'b', 'c']このことを基礎知識として、二つの文字列をとり、一方が他方の部分文字列(substring)になっている時に限りTrueを、そうでなければFalseを返す関数 substringを作れ。 つまり次のような振る舞いをするものである:
substring('abc','cabcd') ⇒ True substring('abc', 'cbab') ⇒ False
# 問題5
6. ファイルdata.txtにあるすべての行を読み込み、それぞれの行の内容を文字列としたリストを得るには次のようにしてできる:
f = open("data.txt","r") # ファイルを開く contents = f.readlines() # それぞれの行の内容(改行コードも含む)を文字列とするリストをcontentsに代入 f.close() # ファイルを閉じるこれを利用して、words.txtにある単語の異なり語数(単語の種類の個数)とそれぞれの単語の出現数を表示する関数 countWordsをつくれ。
# 問題6