まずはPythonで簡単な計算をしてみましょう。各自の画面中の Jupyter Notebook のセルに順次入力して(コピペ可)、「Shift + Enter」してください。
シャープ # を付けるとコメントと見なされ、それ以降の文字はPythonプログラムに無視されます。
文字列と変数
message という変数を定義して、文字列を代入しましょう。
# メッセージ
message = "Pythonはいいぞ"
Jupyter notebook 上では、変数名を呼び出すだけで中身を確認できます。
message
'Pythonはいいぞ'
丁寧に書くなら、また、コード中で出力させたいなら、真面目に print 関数を使いましょう。
print(message)
Pythonはいいぞ
もし変数名のスペルを間違えたりしたら次のようなエラーが出ます。
# マッサージ
massage
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-4-d846b274cc9f> in <module>
----> 1 massage
NameError: name 'massage' is not defined
添字を使って、指定した位置の文字だけ出力できます。
message[0]
'P'
「スライス」という指定方法もあります。下記で「6:8」というのは、ややこしいですが、「0-indexで6番目からスタートし、8の一個手前で終了する」という意味です。ここで「0-index」とは、一番最初を「ゼロ」とみなす数え方のことです。(人間は 1-index でモノを数えることが多いと思いますが、コンピュータは 0-index で数えることが多いのです。
# そして輝くウルトラソウル
message[6:8]
'はい'
添字が文字数を超えていたりするなど範囲指定を間違えていたら次のようなエラーが出ます。
message[15]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-7-8b79e4810453> in <module>
----> 1 message[15]
IndexError: string index out of range
次のようにして、「文字列の足し算」ができます。
message += " 講師はイケメン"
message
'Pythonはいいぞ 講師はイケメン'
「文字列の掛け算」もできます。大事なことなので3回言います。
" 講師はイケメン" * 3
' 講師はイケメン 講師はイケメン 講師はイケメン'
参考記事
「タブ補完」のススメ
コードを真面目に手打ちしていると、頻繁にスペルミスが起こります。それを避けるため「コピペ」と「タブ補完」を活用しましょう。タブ補完とは、たとえば上記のように m から始まる変数がある場合、m とだけ入力して「タブ」キーを押すと補完されます。候補が複数ある場合はその候補のリストが示されます。
予約語
以下の語は、Python の中であらかじめ定義されている「予約語」なので、変数名として使わないようにしましょう。
print(__import__('keyword').kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
print(dir(__builtins__))
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__IPYTHON__', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'display', 'divmod', 'enumerate', 'eval', 'exec', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
簡単な数値演算
普通に数式を入れれば計算してくれます。
33 - 4
29
数値を示す変数を定義して計算することもできます。
lotte = 33
hanshin = 4
lotte - hanshin
29
データの型が違うもの同士を演算しようとすると次のようなエラーが出ます。
lotte - hanshin + "なんでや阪神は関係ないやろ"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-15-7bdf2419ed7a> in <module>
----> 1 lotte - hanshin + "なんでや阪神は関係ないやろ"
TypeError: unsupported operand type(s) for +: 'int' and 'str'
参考記事
リスト(list)
多くの値を「リスト」(list) という変数でまとめて取り扱うことができます。ちなみにこの数字は、ドラゴンボールの主要メンバーの戦闘力 です。
data = [5, 10, 100, 120, 180, 180, 260, 260, 190, 910, 900]
data
[5, 10, 100, 120, 180, 180, 260, 260, 190, 910, 900]
データ型は次のようにして確認できます。
type(data)
list
リストの「長さ」(中に入ってるデータの個数)を確認できます。
len(data)
11
添字を使って、指定した場所のデータにアクセスできます。
data[2]
100
添字の指定が範囲を超えていれば次のようなエラーが出ます。
data[20]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-21-0e53c59a92d0> in <module>
----> 1 data[20]
IndexError: list index out of range
「スライス」という指定方法もあります。下記で「6:8」というのは、ややこしいですが、「0-indexで6番目からスタートし、8の一個手前で終了する」という意味です。ここで「0-index」とは、一番最初を「ゼロ」とみなす数え方のことです。(人間は 1-index でモノを数えることが多いと思いますが、コンピュータは 0-index で数えることが多いのです。
data[6:8]
[260, 260]
「リストの掛け算」をすると、同じリストを指定回数繰り返したようなリストができます。
data * 2
[5,
10,
100,
120,
180,
180,
260,
260,
190,
910,
900,
5,
10,
100,
120,
180,
180,
260,
260,
190,
910,
900]
次のようにして、地球を襲撃しに来た人たちの戦闘力をリストに追加できます。誰のことかは こちら で確認してください。
data.append(1500)
data.append(1200)
data.append(4000)
data.append(18000)
data
[5, 10, 100, 120, 180, 180, 260, 260, 190, 910, 900, 1500, 1200, 4000, 18000]
指定した値を取り除くこともできます。誰が取り除かれたかは こちら で確認してください。
data.remove(190)
data
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 1500, 1200, 4000, 18000]
リストの末尾を取り除くためのメソッドもあります。
data.pop()
18000
data
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 1500, 1200, 4000]
指定したデータが何個あるのかカウントするメソッドもあります。
data.count(180)
2
参考文献
論理演算
以下の論理演算を単独で使うことはほとんどないですが、「IF文」などの条件分岐を理解する上で重要です。
180 == 180
True
910 == 920
False
910 != 920
True
1500 > 1333
True
1307 > 1500
False
(1500 > 1333) and (4000 > 1200)
True
(1500 < 1333) or (4000 > 1200)
True
not (1500 < 1333)
True
戦闘力 530000 の人はデータに入っているでしょうか?
530000 in data
False
もう少し複雑な処理を IF 文で書いてみます。3つの print 関数のうち、どれが出力されて、どれが出力されないか確認してください。
ここから先のプログラムでは、インデント(文頭の空白文字)や、文末の「:」(コロン)などを正しく記述しないと、思った通りの動作をしなくなります。注意して使ってください。
value = 900
if value in data:
print("{} is in data".format(value))
else:
print("{} is not in data".format(value))
print("最終回じゃないぞよ もうちっとだけ続くんじゃ")
900 is in data
最終回じゃないぞよ もうちっとだけ続くんじゃ
ちなみに、次のようにして、ちょっと複雑な文が書けます。
"{} と {} が力を合わせて {} を撃退した。".format(910, 900, 1500)
'910 と 900 が力を合わせて 1500 を撃退した。'
参考文献
辞書(dictionary)
「添字」を任意の値(数字でも文字でも)にした「辞書」というデータ構造があります。
dict_data = {'農夫': 5,
'孫悟空 (12歳)': 10,
'孫悟空 (13歳;亀仙人の修行後)': 100,
'ジャッキー・チュン(亀仙人)': 120}
dict_data['農夫']
5
存在しないキー(添字)を検索しようとするとエラーが出ます。
dict_data['孫悟空']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-44-5c79a6a5f839> in <module>
----> 1 dict_data['孫悟空']
KeyError: '孫悟空'
キーは次のようにして後から追加できます。
dict_data['孫悟空 (16歳)'] = 180
dict_data['天津飯 (20歳)'] = 180
dict_data
{'農夫': 5,
'孫悟空 (12歳)': 10,
'孫悟空 (13歳;亀仙人の修行後)': 100,
'ジャッキー・チュン(亀仙人)': 120,
'孫悟空 (16歳)': 180,
'天津飯 (20歳)': 180}
繰り返し処理
range と for を使って、数字を列挙できます。
for i in range(10):
print(i)
0
1
2
3
4
5
6
7
8
9
始点と終点、および間隔を指定することもできます。
for i in range(110, 125, 3):
print(i)
110
113
116
119
122
while 文を用いた繰り返しというものもありますが、終了条件を間違えたり、 num = num + 1 などの記述を間違えると無限ループになって計算が終わらず、その中で print 関数を使っていると表示が多すぎてマシンが固まることもあるので要注意。
num = 1
while num <= 10:
print(num)
num = num + 1
1
2
3
4
5
6
7
8
9
10
また、while 文が終了した後に変数の値がどうなっているか確認しておくのも大事。
num
11
リストに対する for 文の使い方はこう。
for x in [100, 200, 300]:
print(x)
100
200
300
同じ長さのリストが複数あって、それを同時に回したいときは、zip を使います。
for x, y in zip([100, 200, 300], [400, 500, 600]):
print(x, y)
100 400
200 500
300 600
複数のリストの全組み合わせを出したいなら二重ループにします。
for x in [100, 200, 300]:
for y in [400, 500, 600]:
print(x, y)
100 400
100 500
100 600
200 400
200 500
200 600
300 400
300 500
300 600
添字を参照しながら回したいなら enumerate
for i, x in enumerate([100, 200, 300]):
print(i, x)
0 100
1 200
2 300
リストに格納された数値の合計値を求めてみましょう。
total = 0
for num in data:
print("Power = ", num)
total = total + num
Power = 5
Power = 10
Power = 100
Power = 120
Power = 180
Power = 180
Power = 260
Power = 260
Power = 910
Power = 900
Power = 1500
Power = 1200
Power = 4000
total
9625
辞書に格納されたキー(添字)をリストアップしてみましょう。
for dic_key in dict_data:
print(dic_key)
農夫
孫悟空 (12歳)
孫悟空 (13歳;亀仙人の修行後)
ジャッキー・チュン(亀仙人)
孫悟空 (16歳)
天津飯 (20歳)
次のようにしても同じです。
for dic_key in dict_data.keys():
print(dic_key)
農夫
孫悟空 (12歳)
孫悟空 (13歳;亀仙人の修行後)
ジャッキー・チュン(亀仙人)
孫悟空 (16歳)
天津飯 (20歳)
値をリストアップしてみましょう。
for dic_key in dict_data:
print(dict_data[dic_key])
5
10
100
120
180
180
次のようにしても同じです。
for dic_val in dict_data.values():
print(dic_val)
5
10
100
120
180
180
次のようにして、キーと値を同時に取り出すことができます。
for key, val in dict_data.items():
print(key, " の戦闘力は ", val, " です。")
農夫 の戦闘力は 5 です。
孫悟空 (12歳) の戦闘力は 10 です。
孫悟空 (13歳;亀仙人の修行後) の戦闘力は 100 です。
ジャッキー・チュン(亀仙人) の戦闘力は 120 です。
孫悟空 (16歳) の戦闘力は 180 です。
天津飯 (20歳) の戦闘力は 180 です。
リスト内包表記
data の数値を1個ずつ取り出して、3倍界王拳してみましょう。
data3 = []
for x in data:
data3.append(x * 3)
data3
[15, 30, 300, 360, 540, 540, 780, 780, 2730, 2700, 4500, 3600, 12000]
同じことを「リスト内包表記」という書き方で記述できます。
data3_naiho = [x * 3 for x in data]
data3_naiho
[15, 30, 300, 360, 540, 540, 780, 780, 2730, 2700, 4500, 3600, 12000]
「戦闘力が 1000 未満の人は3倍界王拳が使えない」という制限をかけてみましょう。
[x * 3 for x in data if x >= 1000]
[4500, 3600, 12000]
上記の計算だと、界王拳が使えない人は消されてしまいましたが、界王拳が使えない人をそのままで生き残らせたいなら次のようになります。
[x * 3 if x >= 1000 else x for x in data ]
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 4500, 3600, 12000]
参考文献
関数を定義して使う
界王拳3倍を関数にしてみます。ただし、戦闘力が1000未満の場合は3倍にならず、そのままの戦闘力であるものとします。
def kaioh_ken_3bai(a):
if a >= 1000:
a = a * 3
return a
data3 = []
for x in data:
data3.append(kaioh_ken_3bai(x))
data3
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 4500, 3600, 12000]
リスト内包表記するとこんな感じです。
[kaioh_ken_3bai(x) for x in data]
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 4500, 3600, 12000]
map という関数を使って界王拳3倍する方法もあります。
list(map(kaioh_ken_3bai, data))
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 4500, 3600, 12000]
「ラムダ式」という異名を持つ「無名関数」を使っても界王拳3倍できます。このようなラムダ式をつかって、、、
(lambda x: x * 3 if x >= 1000 else x)(1000)
3000
このようにします。
list(map(lambda x: x * 3 if x >= 1000 else x, data))
[5, 10, 100, 120, 180, 180, 260, 260, 910, 900, 4500, 3600, 12000]
関数を定義することの利点は、同じ処理を何度も繰り返したいときに使いまわせることと、次のように「再帰的」(自分が自分を呼び出す)ことができることです。次は有名なフィボナッチ数の出し方です。
def calc_fib(n):
if n == 1 or n == 2:
return 1
else:
return calc_fib(n - 1) + calc_fib(n - 2)
calc_fib(10)
55
チェンジ
整列アルゴリズムなど、いくつかの有名なアルゴリズムでは、変数の中身を入れ替える操作を行います。たとえば、次のような変数の中身を入れ替えたいとします。
goku = 180000
ginyu = 120000
goku, ginyu
(180000, 120000)
次のようにして、中身を入れ替えることができます。
goku, ginyu = ginyu, goku
goku, ginyu
(120000, 180000)
クラスとインスタンス
最後に、クラスとインスタンスについて説明します。たとえば「人」をクラスとして表現すると
class Person:
def self_introduction(self):
print("私は {} 。私の戦闘力は {} です。".format(self.name, self.power))
下記のようにして、Personというクラスに属する freeza というインスタンスが作れます。
freeza = Person()
freeza.name = 'フリーザ'
freeza.power = 530000
freeza.self_introduction()
私は フリーザ 。私の戦闘力は 530000 です。
もう少し凝ったクラスを作ってみましょう。
- 初期化する関数 init を設定する
- 変身するための関数を定義する
- 変身は3回までとする
class Person:
def __init__(self, x, y):
self.name = x
self.power = y
self.stage = 1 # 第1形態からスタート
self.max_transform = 3 # 3回まで変身できる
def transform(self): # 変身
if self.stage <= self.max_transform:
print("変身")
self.power *= 2 ** self.stage
self.stage += 1
else:
print("マックスパワーの半分も出せばキミを宇宙のチリにすることができるんだ…")
def self_introduction(self):
print("私は {} (第 {} 形態)。私の戦闘力は {} です。".format(self.name, self.stage, self.power))
print("私は変身をあと {} 回残しています。".format(self.max_transform - self.stage + 1))
初期化の関数を定義し、その関数は引数を必要とするので、先ほどと同じようにインスタンスを作るとエラーになります。
freeza = Person()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-82-140a6c210b6b> in <module>
----> 1 freeza = Person()
TypeError: __init__() missing 2 required positional arguments: 'x' and 'y'
引数の数を正しく指定すると動きます。
freeza = Person('フリーザ', 530000)
freeza.self_introduction()
私は フリーザ (第 1 形態)。私の戦闘力は 530000 です。
私は変身をあと 3 回残しています。
freeza.transform()
変身
freeza.self_introduction()
私は フリーザ (第 2 形態)。私の戦闘力は 1060000 です。
私は変身をあと 2 回残しています。
freeza.transform()
変身
freeza.self_introduction()
私は フリーザ (第 3 形態)。私の戦闘力は 4240000 です。
私は変身をあと 1 回残しています。
freeza.transform()
変身
freeza.self_introduction()
私は フリーザ (第 4 形態)。私の戦闘力は 33920000 です。
私は変身をあと 0 回残しています。
freeza.transform()
マックスパワーの半分も出せばキミを宇宙のチリにすることができるんだ…
freeza.self_introduction()
私は フリーザ (第 4 形態)。私の戦闘力は 33920000 です。
私は変身をあと 0 回残しています。
変身の履歴が残っているので、これ以上変身できません。