概要
前回の環境構築編の続きです。
今回はPythonの文法をざざっと見ていきます。
Pythonの特徴
Pythonは、「シンプルで習得がしやすいオブジェクト指向言語」と呼ばれています。
Pythonは古くからプログラミング学習用言語として使われていますが、
最近は、GoogleAppEngineとして使われていたり、機械学習やデータ操作系のプラグインが豊富でかなり注目されています。
(日本では、そこまで目立ってはいないですが、海外では大人気らしい。)
今回は、広く使われているPythonの2.7.xを使って文法を復習したいと思います。
(2.7.12を使います。)
Pythonの文法
セミコロンは非推奨
Pythonの文法では文末のセミコロンは非推奨です。
(次回以降で解説するpep8で定義されています。)
文末は改行で表現します。
コメント
#でコメントできます。
日本語文字を扱う
Pythonでコード上に日本語文字をいれると以下のエラーが吐かれます。
File "index.py", line 2
SyntaxError: Non-ASCII character '\xe3' in file index.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for
details
コード上で日本語を扱うときは、UTF-8を明示的に宣言する必要があります。
# coding: UTF-8
# 上記で、コード上で日本語が使えるよ
print 'hello' # こんにちはと挨拶するよ
変数
特になんの接頭語もなく宣言できます。
msg = 'hello from gemcook'
print msg
データ型
Pythonで扱えるデータ型は以下となります。
- 数値
- 文字
- 真偽値(True/False)
- None
- 関数・オブジェクト
- 要素が並んだもの
- 文字列(文字が並んだもの)
- リスト(データが並んだもの(配列))
- タプル(データが並んだもの(変更ができない))
- セット(データが並んだもの(重複を許さない))
- ディクショナリ(key-valueで管理)
数値型
小数と整数の演算
小数と整数を演算すると、小数になります。
切り捨ての整数
整数同士を割り算した場合、切り捨ての割り算結果がでます。
print 10 / 3 # 3
小数も出したければ、以下の様にすれば良いです。
print 10 / 3.0 # 3.3333333333
文字列
日本語文字列を出力する場合
文字列の先頭に「u」(unicode)をつけて出力する。
(uを付けないと、文字列検索時に正しい結果が得られません。)
print 'hello' + 'world' # helloworld
print u'は' *5 # ははははは
エスケープ文字
\で記述します。
print 'It\'s a pen!'
改行やエスケープが多い時
'''と'''で囲むとその範囲は改行したら改行、強制エスケープとなります。
print '''
<html lang="ja">
<body>
</body>
</html>
'''
文字列に関する命令
s = 'abcdefghi'
print len(s) # 9
print s.find('c') # 2(存在しなければ-1を返します)
print s[2] # c
print s[2:5] # cde(5番目の1つ前までを返す)
print s[2:] # cdefghi
print s[:5] # abcde
print s[2:-1] # cdefgh(一番最後の文字の1つ前までを返す)
数値と文字の変換
JSなど他の言語で、数値っぽい文字は自動的に数値に変換してくれたりします。
('1'は1と判断)
Pythonは自動で型変換を行わない為、明示的に型変換を行う必要があります。
print 5 + '5' # エラーとなる。
整数に変換したい場合は、以下の様にする。
print 5 + int('5') # 10
文字列に関しも同じである。
age = 20
print 'i am ' + str(age) + ' years old'
リスト型
他の言語では配列と呼ばれるものにあたる。
sales = [
255,
100,
353
]
リストの中身はどんな型の要素でも代入可能である。
sales = [
255,
100,
353,
'apple'
]
リストに関しても、文字列と同じ様な命令を使う事ができる。
sales = [
255,
100,
353,
'apple'
]
sales2 = [
500,
'orange'
]
print sales # [255, 100, 353, 'apple']
print sales * 2 # [255, 100, 353, 'apple', 255, 100, 353, 'apple']
print sales + sales2 # [255, 100, 353, 'apple', 500, 'orange']
print len(sales) # 4
print sales[3] # 'apple'
sales[2] = 250
print sales # [255, 100, 250, 'apple']
存在チェックの命令もある。
sales = [
255,
100,
353,
'apple'
]
print 100 in sales # True
数字の連番のリストを作る命令もある。
print range(3) # [0, 1, 2]
print range(1, 3) # [1, 2]
print range(3, 10, 2) # [3, 5, 7, 9]
リスト型の便利な命令
listはリスト型の変数、strは文字列型の変数とする。
- list.sort()
- リストを小さい順に置き換える。
- list.reverse()
- リストの順番を逆にする
- 大きい順に並べるわけではない。
- str.split([区切り文字])
- 文字を区切り文字で区切った配列を返してくれる。
d = '2013/12/15'
print d.split('/') # [2013, 12, 15]
- str.join(list)
- strの文字列でlistの文字を区切って文字列を返す。
list = ['a', 'b', 'c']
print string.join(list)
タプル型
タプルは基本はリストと同じです。
ただし、要素の変更ができないという特徴があります。
命令も配列と同じものが使えます。
- len
- in
- sort
- reverse
- split
- join
tuple1 = (2, 5, 8)
tuple2 = (5, 5, 5)
print tuple1 + tuple2 # (2, 5, 8, 5, 5, 5)
print 2 in tuple2 # True
tuple1[2] = 10 # これはエラーになる。
タプルとリストの相互変換
文字列と数値の変換と同じで型変換命令を使う事で、柔軟にタプルとリストを切り替える事が可能です。
array = [
'dog',
'cat',
'tiger'
]
print array # ['dog', 'cat', 'tiger']
tupleChange = tuple(array)
listChange = list(tupleChange)
print tupleChange # ('dog', 'cat', 'tiger')
print listChange # ['dog', 'cat', 'tiger']
タプルを使う意味としては、明示的に変更できないデータだよと教える事のほかに、
処理速度の向上にもつながります。
タプルが利用できるタイミングでは、タプルを利用する様にしましょう。
セット(集合型)
セットもリストやタプルと同じで、データが並んだものですが、
重複を許さないという特徴があります。
集合型と呼ばれている様に集合の計算を行うことができます。
セットの作り方
a = set([1, 2, 3])
b = set([3, 4, 5])
また、重複しているデータは無視されます。
print set([1, 2, 3, 3, 3, 4, 5]) # set([1, 2, 3, 4, 5])
集合の計算
# coding: UTF-8
a = set([1, 2, 3, 6])
b = set([3, 4, 5, 7])
# 差集合(aにあってbにないもの)
print b - a # set([1, 2, 6])
# 和集合(aとbにあるもの)
print a | b # set([1, 2, 3, 4, 5, 6, 7])
# 積集合(aとbで重複しているもの)
print a & b # set([3])
# aとbのどちらかにしかないもの
print a ^ b # set([1, 2, 4, 5, 6, 7])
ディクショナリ型
JSでいうところのオブジェクトです。
Swiftの辞書型の方がイメージが近いと思います。
mugiwara = {
'luffy': 100000000,
'zoro': 77000000
}
print mugiwara # {'zoro': 77000000, 'luffy': 100000000}
注意点としては、出力する要素は順不同であるという事です。
代入や取得に関しては、リストなどと変わりません。
mugiwara = {
'luffy': 100000000,
'zoro': 77000000
}
print mugiwara['luffy'] # 100000000
mugiwara['zoro'] = 120000000
print mugiwara # {'zoro': 120000000, 'luffy': 100000000}
in命令でkeyの存在チェックも行えます。
mugiwara = {
'luffy': 100000000,
'zoro': 77000000
}
print 'luffy' in mugiwara # True
ディクショナリ型のメソッド
ディクショナリ型ならではのメソッドです。
mugiwara = {
'luffy': 100000000,
'zoro': 77000000
}
# keyの一覧を取得する。
print mugiwara.keys() # ['zoro', 'luffy']
# valueの一覧を取得する。
print mugiwara.values() # [77000000, 100000000]
# key-valueの一覧を取得する。
print mugiwara.items() # [('zoro', 77000000), ('luffy', 100000000)]
文字列型にデータを組み込む方法
わざわざ型変換を行わずとも、文字列型に他の型を埋め込む事も可能です。
a = 3000000000
b = 1.234
c = 'luffy'
d = {
'choppa': 50,
'usoppu': 300000000
}
# 整数値を組み込む
print 'decimal: %010d' % a # 3000000000
# 小数値を組み込む
print 'float: %.1f' % b # 1.2
# 文字列を組み込む
print 'name: %s' % c # luffy
# 辞書型を組み込む
print 'berry: %(choppa)d' % d # 30000000
# 複数の値を組み込む
print '%s: %d' % (c, a) # luffy: 300000000
整数値
- %dで表します(decimal)
- 前に桁を入れる事でその桁数で表示できます。
- 桁数の前に0を入れる事で0埋めできます。
小数値
- %fで表します(float)
- 前に.Xといれる事で、小数点以下の桁数を指定できます。
文字列
- %sで表します(string)
辞書型
- %([keyName])[valueの型の文字]で表します。
その他
- 複数の値を代入する事も可能です。
- その際には、()で囲みます。
型チェック
Pythonの型チェックは以下の通りです。
score = 70
print type(score) # <type, int>
また、Ture/Falseで返す方法もあります。
score = 70
print isinstance(score, int) # True
print isinstance(score, str) # False
条件分岐
いつも通りifを使う。
条件式の()は不要です。
条件判定後の処理はインデントで字下げして表現します。
# coding: UTF-8
score = 70
if 60 < score < 80:
print 'ok' # 'ok'
比較演算子
あるある比較演算子です。
- <
-
- <=
-
=
- ==
- !=
- is(インスタンスの同一性をチェック(値が一緒でもFalse))
- is not(インスタンスの同一性をチェック(値が違っていてもFalse))
論理演算子
論理演算子はより直感的になっています。
(JSなら &&, ||, !)
- and
- or
- not
if else文
if else文もほぼ他の言語と変わりません。
elifだけが少し特徴的なので覚えておきましょう。
score = 70
if int(score) > 60:
print 'ok'
elif score > 40:
print 'soso'
else:
print 'ng'
1行で条件分岐
たいていの言語で、条件分岐を1行で描く方法が存在します。
(JSの三項演算子など)
Pythonの1行で条件分岐は少しトリッキーですが、
シンプルなコードを書く為にも丸暗記してしまいましょう。
score =70
print 'ok' if score > 60 else 'ng'
繰り返し
for文が使えます。
以下が構文となります。
リスト型のループ
sales = [13, 3523, 31, 238]
result = 0
for sale in sales:
result += sale
else:
print result
else以下は、繰り返しが終了した際に、一度だけ実行する処理となります。
range()
単純に数値の連番を表示した場合は、range()が利用できる。
for i in range(10):
print i # 0 1 2 3 4 5 6 7 8 9
continueとbreak
ループ処理を途中でスキップしたり、終了したりする時は、continueとbreakを使います。
for i in range(10):
if i == 3:
continue
elif i == 5:
break
辞書型のループ
辞書型のループはiterXXXX()関数を利用します。
# coding: UTF-8
mugiwara = {
'luffy': 300,
'zoro': 100,
'sanji': 50
}
# key, values両方取得する。
for key, value in mugiwara.iteritems():
print 'key: %s, value: %d' % (key, value)
# keyのみ取得する。
for key in mugiwara.iterkeys():
print key
# valueのみ取得する。
for value in mugiwara.itervalues():
print value
whileループ
whileループもあります。
# coding: UTF-8
n = 0
while n < 10:
print n
n += 1
else:
print 'finish'
関数
普通の関数です。
複数の処理をまとめて登録しておきます。
defキーワードを利用します。
文法ルールとして(pep8)、関数を定義する際は、2行blank行を作って下さい。
# coding: UTF-8
def sayHello():
print 'hello'
sayHello()
引数
もちろん引数を取ることも可能です。
# coding: UTF-8
def sayHello(name, num):
print 'hello, %s.' % name * num
sayHello('Luffy', 2) # hello, Luffy.hello, Luffy.
引数の初期化
登録側で=で初期値を設定します。
(pep8では、間位にスペースをとりません。)
# coding: UTF-8
def sayHello(name, num=3):
print 'hello, %s.' % name * num
sayHello('Luffy') # hello, Luffy.hello, Luffy.hello, Luffy.
引数の指定
実行側で引数の指定を明示的に行うことも可能です。
# coding: UTF-8
def sayHello(name, num=3):
print 'hello, %s.' % name * num
sayHello('Luffy') # hello, Luffy.hello, Luffy.hello, Luffy.
sayHello(num=2, name='Zoro') # hello, Zoro.hello, Zoro.
return文
登録側でreturn命令を使えば、単純な値として、関数の結果を返せます。
# coding: UTF-8
def sayHello(name='no name'):
return 'hello, %s' % name
print sayHello(name='Nami')
空関数の定義
とりあえず関数の実体のみ定義して、中身の処理は後で記述したい場合があると思います。
そんなとき他の言語であれば、空関数を以下の様に定義すると思います。
(JSの時)
# 実体のみで、中身の記述はまだの関数
function sayHello() {
}
Pythonでは{}で関数は定義しないし、インデントで文末を表現する為、空の関数を定義する為だけの、pass命令が準備されています。
def sayHello2():
pass
print sayHello2() # None
pass命令を利用することで、is not definedエラーを回避することができます。
変数のスコープ
Pythonでは関数内の変数は関数内でのみ有効な変数となります。
# coding: UTF-8
name = 'Luffy'
def sayHello():
name = 'Zoro'
# Zoroじゃないよ
print name # Luffy
map
リストの各要素に対して、関数を実行していく命令です。
map命令は以下の様に実行します。
# coding: UTF-8
listItems = [2, 5, 8]
def double(x):
return x * x
map(double, listItems) # [4, 25, 64]
lambda命令
Pythonでは、たった1回しか使わない様な無名の関数を定義することも可能です。
先ほどの、mapと共に対象の値を2倍するだけのlambdaを定義しています。
# coding: UTF-8
listItems = [2, 5, 8]
result = map(lambda x: x * x, listItems)
print result # [4, 25, 64]
lambdaのすぐ後ろには任意の引数を指定します。
(mapはリストの要素を1つずつxに代入します。)
lambdaはreturn文で値のみが返却されるイメージです。
オブジェクト(クラス・インスタンス)
クラスの作成
# coding: UTF-8
# 決まり文句として、classの引数にobjectを取る。
class User(object):
# __init__はJSでいうconstructor
# 第1引数のselfは必ず初期化時に必要
def __init__(self, name):
self.name = name
# 関数内で対象のクラスのプロパティ・メソッドを利用する際は、
# 引数に第1引数にはselfを取る。
def greet(self):
print 'my name is %s' % self.name
bob = User('Bob')
tom = User('Tom')
print bob.name # 'Bob'
bob.greet() # my name is Bob
tom.greet() # my name is Tom
ポイント
- classの引数のオブジェクトは決まり文句として、クラス作成の際には指定する。
-
__init__
はクラスがインスタンス化された際の初期化メソッドで、Pythonが準備している。 - 関数を定義する際は必ず、第1引数のself(JSならthis)は必須。
- インスタンス化はnewとかかかない。
クラスの継承
クラスを継承する際は、classの引数に継承元のクラス名を記載する。
# coding: UTF-8
class User(object):
def __init__(self, name):
self.name = name
def greet(self):
print 'my name is %s' % self.name
class SuperUser(User):
def shout(self):
print '%s is SUPER!' % self.name
luffy = SuperUser('Luffy')
luffy.shout() # Luffy is SUPER!
モジュール
Pythonが予め準備してくれている、便利な命令が詰まったもの。
どんなモジュールがあるかは公式サイトを参考にして下さい。
Pythonが準備しているモジュールは大きく3種類あります。
組み込み型モジュール
len, split, joinなどimport文を使わなくても元々準備されているモジュール
標準モジュール
Pythonが準備してくれているが、importしないと使えないモジュール
外部モジュール
pipで、モジュールをインストールした上で、importして利用するモジュール
以下、外部モジュールをimportする例です。
# coding: UTF-8
import math
import random
# datetimeモジュールの中のdateモジュールのみをimport
from datetime import date
print math.ceil(5.2) # 6.0
for i in range(5):
print random.random()
print date.today() # 2016-10-08
ポイント
datetimeの様な大きなモジュールは、必要部分だけ切り出すことも可能です。
その場合は、from命令を利用します。
まとめ
Pythonは独特の構文もありますが、基本的に覚えやすくて、可読性もかなり高いと思います。
書いていて気持ちの良い言語だと思います。
次回はPythonで一番人気のフレームワークDjangoを調査したいと思います。