動的プログラミング言語を知っている人のためのPython入門

原著: Matthew Brett; 翻訳: 黒下彰喜, 本多皓一, 根本清貴

本チュートリアルは、Brisk introduction to Python を、著者のMatthew Brettの許諾を得て翻訳したものです。


このページは、動的プログラミング言語を既に理解している人のためのPython入門です。動的プログラミング言語には、MatlabやRがあげられます。

このページの使い方

このページを最初から最後まで通して読んでください。 Pythonのすべての基本的なデータ型を扱うとともに、関連するPythonの言語の特徴を説明します。

読みながら Jupyter notebook を開き、コードを打ち込むかコピー&ペーストして実行すると良いでしょう。

このページが終わるまでには、Pythonの概要が理解でき、この言語を学ぶときの導きになるでしょう。

Pythonには2種類の数があります。それは整数と浮動小数点です。 Pythonにおいて、整数はint型オブジェクトで、浮動小数点はfloat型オブジェクトです:

In [1]:
a = 99
In [2]:
print(type(a))
<class 'int'>
In [3]:
b = 99.0
In [4]:
print(type(b))
<class 'float'>

int型とfloat型は、 intfloat を使って次のように作ります:

In [5]:
float('1')
Out[5]:
1.0
In [6]:
float(1)
Out[6]:
1.0
In [7]:
int('1')
Out[7]:
1
In [8]:
int(1)
Out[8]:
1

int型とfloat型がまざった四則演算の結果はfloat型になります:

In [9]:
a + b
Out[9]:
198.0
In [10]:
a * b
Out[10]:
9801.0

int型をint型で割ってもfloat型になります。ただしこれはPython3以降での話です。(脚注[1]参照):

In [11]:
1 / 2
Out[11]:
0.5

割り算において、商だけ必要なときは、 // を使います:

In [12]:
1 // 2
Out[12]:
0
In [13]:
1.0 // 2.0
Out[13]:
0.0

Pythonには round と呼ばれる組み込み関数があります: (訳注: 偶数への丸めであり、四捨五入ではありません)

In [14]:
round(5.0 / 2.0)
Out[14]:
2

% 演算子は、整数の割り算における余りを出力します(modとも言います):

In [15]:
5 % 2
Out[15]:
1
In [16]:
5.0 % 2.0
Out[16]:
1.0

True と False

True と False はPythonでは特別なオブジェクトです。これらは真偽を表すためのブール型です:

In [17]:
type(True)
Out[17]:
bool
In [18]:
type(False)
Out[18]:
bool
In [19]:
True == False
Out[19]:
False
In [20]:
True == True
Out[20]:
True
In [21]:
False == False
Out[21]:
True

ブール値を使った論理式には、論理演算子 and, or そして not が使えます:

In [22]:
True and True
Out[22]:
True
In [23]:
True and False
Out[23]:
False
In [24]:
True or False
Out[24]:
True
In [25]:
False or False
Out[25]:
False
In [26]:
not True
Out[26]:
False
In [27]:
True and not False
Out[27]:
True

None

None もPythonでは特別なオブジェクトです。Pythonの作法として、操作の結果適切な値が得られなかった場合や、パラメータの値がない場合、しばしば None を使います:

In [28]:
type(None)
Out[28]:
NoneType

Pythonの他の値とは違い、 None はデフォルトでは何も表示されません:

In [29]:
None

等号

MATLABやRと同様に、= は代入に使い、== は等しいことの評価に使います:

In [30]:
a = 1
a
Out[30]:
1
In [31]:
a == 1
Out[31]:
True

Rと同様に、Python は != をオブジェクト同士が等しくないことの評価に使います。 ~= を使うMATLABとは異なります:

In [32]:
a != 1
Out[32]:
False

“If” 文、ブロック、インデント

Pythonで条件文は次のようになります:

In [33]:
my_var = 10
if my_var == 10:
    print("The conditional is True!")
    print("my_var does equal 10")
The conditional is True!
my_var does equal 10

条件文の1行目には、条件式を記載し、コロンで終わります。これをif式と呼びましょう。 if式に続けてインデントされた行が続きます。これらのインデントされた行をifブロックと呼びます。 Pythonはif式が True のときだけifブロック内の文を実行します。 例えば次の場合、if式が False なので、ブロックは実行されません:

In [34]:
my_var = 11
# 今回は条件は False になります
if my_var == 10:  # "if テスト"
    # インデントがついている行が "if ブロック" になります
    print("The conditional is True!")
    print("my_var does equal 10")

if式と同じレベルのインデントに戻った行で、ブロックが終わります。 ifブロック内に別のインデントされたブロック(例えば別のifブロック)がなければ、ブロック内のすべての行は同じインデントになります。 RとMATLABのif文については注[2]を参照してください。 ifブロックに条件文 else: の別のブロックが続く場合があります。 そのブロックは最初の条件式が False のときだけ実行されます:

In [35]:
my_var = 11
if my_var == 10:
    print("The conditional is True!")
    print("my_var does equal 10")
else:
    print("The conditional is False!")
    print("my_var does not equal 10")
The conditional is False!
my_var does not equal 10

さらに他の条件ブロックを持つ条件式がある場合もあります。そのときは elif 条件式 を使います。elif は else if の略です:

In [36]:
my_var = 12
if my_var == 10:
    print("The conditional is True!")
    print("my_var does equal 10")
elif my_var == 11:
    print("The second conditional is True!")
    print("my_var does equal 11")
elif my_var == 12:
    print("The third conditional is True!")
    print("my_var does equal 12")
else:
    print("All conditionals are False!")
    print("my_var does not equal 10, 11 or 12")
The third conditional is True!
my_var does equal 12

“While” 文

while文も最初の条件式にインデントされたブロックが続きます。1000未満のフィボナッチ数のうち最も大きい数を見つけ出す例を示しましょう:

In [37]:
last_but_1 = 0
fibonacci = 1
while fibonacci < 1000:
    last_but_2 = last_but_1
    last_but_1 = fibonacci
    fibonacci = last_but_2 + last_but_1
print("Largest Fibonacci < 1000 is", last_but_1)
Largest Fibonacci < 1000 is 987

最初のwhile条件式: while fibonacci < 1000: に注目してください。この後にインデントされたwhileブロックが続きます。if文とは異なり、Pythonはwhile条件式がFalseと判定されるまではwhileブロック内に記述された文を実行し続けます。

リスト

リストは以下のようにして作成します:

In [38]:
my_list = [9, 4, 7, 0, 8]
In [39]:
my_list
Out[39]:
[9, 4, 7, 0, 8]
In [40]:
type(my_list)
Out[40]:
list

リストの要素にはどのオブジェクト型でも使うことができます。要素にリストを使うこともできます:

In [41]:
mixed_list = [9, 3.0, True, my_list]
In [42]:
mixed_list
Out[42]:
[9, 3.0, True, [9, 4, 7, 0, 8]]
In [43]:
type(mixed_list)
Out[43]:
list

PythonのリストはMATLABにおけるセル配列やRにおけるリストに似ています。

“for” ループと繰り返し

リストに対しては繰り返し処理ができます。繰り返しとは、リストのようなコンテナ(訳注:複数のオブジェクトを格納できるデータ型のこと)から要素を次々に取り出すことです。リストからの繰り返しにはforループを利用できます:

In [44]:
for e in my_list:
    print(e)
9
4
7
0
8

forループはif文やwhileループと同様に、最初の行がコロンで終わり、そこにインデントされたブロックが続きます。

forループの最初の行は、次のようになります:for ループ変数 in コンテナ:。このコンテナとはそこから要素を取り出すためのものです。forループの繰り返しにおいて、Pythonはコンテナから新しい要素を取り出し、ループ変数に代入します。コンテナの各々の要素に対してPythonはforブロックを実行します。

脚注[3]にPython、R、MATLABでの同じ内容を表すforループを示しました。

連続整数に対する繰り返しにおいてforループをどのように書くかについては、Rangeのセクションを確認してください。

リストはシーケンスである

シーケンスはPythonオブジェクトの型の1つです。決まった要素の順番を持ち、長さを持ち、イテラブル(繰り返し可能)であり、整数でインデックス付けすることができ、スライスができます(下記参照)。もしオブジェクトsがシーケンスならば、以下のようになります:

  • sは長さを持ち、それはlen(s)で分かります;

  • for 要素 in s: # 要素を用いた処理 の形でsの要素に対する繰り返し処理が行えます;

  • 位置nの要素は s[n] で取得できます;

  • sをスライスすることで別のシーケンスのオブジェクトを作成できます。例えば、 s[0:n] は、sの最初からn個の要素を含む新たなシーケンスとなります。

In [45]:
# 長さを持ちます
len(my_list)
Out[45]:
5
In [46]:
# 繰り返せます
for e in my_list:
    print(e)
9
4
7
0
8
In [47]:
# インデックスで特定の要素を表示できます
my_list[1]
Out[47]:
4
In [48]:
# スライスできます
my_list[0:2]
Out[48]:
[9, 4]

Pythonのインデックスは0を基準とする

Pythonでは、シーケンスのインデックスは0から始まります。最初の要素にはインデックス0が、2番目の要素にはインデックス1が割り当てられ、以下同様に続きます:

In [49]:
my_list[0]
Out[49]:
9
In [50]:
my_list[1]
Out[50]:
4

負のインデックス

インデックスに負の数を使うと、リストの終わりから逆順に数え上げられます。例えば、インデックス -1 を使うとリストの最後の要素を取得できます:

In [51]:
my_list
Out[51]:
[9, 4, 7, 0, 8]
In [52]:
my_list[-1]
Out[52]:
8

上の -1 のインデックスは以下と同じです:

In [53]:
my_list[len(my_list) - 1]
Out[53]:
8

最後から3番目の要素はこうなります:

In [54]:
my_list[-3]
Out[54]:
7

全てのPythonの変数はポインタである

Pythonでは、変数名はオブジェクトがメモリ上に保存されている場所を指し示します。そのため、Pythonの変数はポインタと呼ばれることもあります。

標準的なPythonを実行している場合、変数がメモリ上のどこにあるかを id() 関数を用いて確認することが出来ます。コンピュータのメモリ上の場所を示すいくらか長い整数が出力されます:

In [55]:
id(my_list)
Out[55]:
139943313314568

another_variable=a_variable を実行する場合、 another_variale という名称は a_variable という名称と同じオブジェクトを指し示すということを伝えていることになります。そのため、その変数はメモリ上の同じ場所を指し示します:

In [56]:
another_list = my_list
In [57]:
another_list
Out[57]:
[9, 4, 7, 0, 8]
In [58]:
id(another_list)
Out[58]:
139943313314568
In [59]:
id(another_list) == id(my_list)
Out[59]:
True

リストは変更可能である

リストはミュータブル mutable なオブジェクトです。ミュータブルとは、新しいリストを作らなくてもリストの要素を変更できるということを意味します:

In [60]:
my_list[1] = 99
In [61]:
my_list
Out[61]:
[9, 99, 7, 0, 8]

リストはミュータブルなため、全てのPython変数がポインタであることは心に留める必要があります:

In [62]:
another_list = my_list
In [63]:
another_list
Out[63]:
[9, 99, 7, 0, 8]
In [64]:
id(another_list) == id(my_list)
Out[64]:
True

my_listanother_listと同じオブジェクトを指し示すため、my_list(によって指し示されるオブジェクト)を修正すると、another_listの値も修正されます。なぜならmy_listanother_listとは同じリストを指し示すからです:

In [65]:
my_list[1] = 101
In [66]:
another_list
Out[66]:
[9, 101, 7, 0, 8]

リストの結合

2つのリストを+で足し合わせると、2つのリストを連結した新たなリストが出力されます:

In [67]:
new_list = my_list + [False, 1, 2]
In [68]:
new_list
Out[68]:
[9, 101, 7, 0, 8, False, 1, 2]

要素の追加と除去

append メソッドで要素を追加することができます。

メソッドは、オブジェクトに備わっている関数です。Pythonにおける関数について詳しくは関数のセクションをご覧ください。

appendがメソッドであることはmy_list.appendの値を表示することで分かります:

In [69]:
my_list.append
Out[69]:
<function list.append>

メソッドを呼び出すには、メソッドに渡したい引数をかっこ内に加えます。この場合追加する要素に引数が渡されます:

In [70]:
my_list.append(20)
In [71]:
my_list
Out[71]:
[9, 101, 7, 0, 8, 20]

appendメソッドはリストを返さず、その場でリストを変更してしまうことに注意しましょう。PythonではappendメソッドからはNoneが返ってきます:

In [72]:
result = my_list.append(42)
In [73]:
result == None
Out[73]:
True

他のメソッドでも直接リストを変更するものがあります。例えば sort メソッドです:

In [74]:
new_list = [10, 1, 3]
In [75]:
result = new_list.sort()
# 戻り値は None です
In [76]:
result == None
Out[76]:
True
In [77]:
# しかし、元のリストはソートしたために昇順になっています
new_list
Out[77]:
[1, 3, 10]

pop メソッドを使うとリストから要素を除去できます:

In [78]:
# リストから最後の要素を除いたリストを返します
my_list.pop()
Out[78]:
42
In [79]:
my_list
Out[79]:
[9, 101, 7, 0, 8, 20]
In [80]:
# リストから3番目の要素を除いたリストを返します
my_list.pop(2)
Out[80]:
7
In [81]:
my_list
Out[81]:
[9, 101, 0, 8, 20]

スライス

リストなどのシーケンスからは、一部を切り出すことができます。これをスライスと呼びます。スライスするには、取り出したい領域を指定子として角括弧に入れます。例えば、ここではリストの最初の3要素が返されます:

In [82]:
my_list[0:3]
Out[82]:
[9, 101, 0]

角括弧の後、そして、コロンの前にある最初の数字は、開始インデックスです。この場合、インデックスは0なので、最初の要素からはじまります。コロンの後の2番めの数字は終止インデックスです。この数字は終わりのインデックスに1を足したものになります。この場合はインデックス0, 1, 2を返すことになります。つまり、要素はインデックス3まで返すのですが、インデックス3は含まれないということになります。

最初の数字(開始インデックス)を省略した場合、Pythonは開始インデックスは0とみなします:

In [83]:
my_list[:3]
Out[83]:
[9, 101, 0]

2番目の数字を省略した場合、Pythonはリストの長さを終止インデックスと見なします:

In [84]:
my_list[2:]
Out[84]:
[0, 8, 20]
In [85]:
my_list[2:len(my_list)]
Out[85]:
[0, 8, 20]

どちらの数字も省略することもでき、その場合リストの要素全てが返されます。これは、最初のリストと同じ要素を含む新規のリストを作りたい場合に有用です:

In [86]:
another_list = my_list[:]
In [87]:
another_list
Out[87]:
[9, 101, 0, 8, 20]

これは新規のリストオブジェクトであるので、オリジナルのリストを変更しても新規のリストは変更されません:

In [88]:
my_list[1] = 999
In [89]:
another_list
Out[89]:
[9, 101, 0, 8, 20]

2番目のコロンと3番目の数字を指定することもできます。このとき、3番目の数字がステップサイズです。例えば、リストの1つおきの要素を取得するなら:

In [90]:
my_list[0:len(my_list):2]
Out[90]:
[9, 0, 20]
In [91]:
# 終止インデックスが省略された場合、リストの長さが終止インデックスとみなされます
my_list[0::2]
Out[91]:
[9, 0, 20]

開始インデックスと終止インデックスに負の数を使うことができます。インデックスに関しては、負の開始値と終止値はリストの終わりから逆順に数えます:

In [92]:
my_list
Out[92]:
[9, 999, 0, 8, 20]
In [93]:
my_list[-4:-2]
Out[93]:
[999, 0]

ステップに負の数を用いると、開始インデックスから終止インデックスまで逆順に数えます:

In [94]:
my_list[4:1:-1]
Out[94]:
[20, 8, 0]

負のステップサイズを用い、開始インデックスを指定しなかった場合、開始インデックスのデフォルトはリストの最後の要素となります。終止インデックスを指定しなかった場合は、終止インデックスはインデックス0より左側となります:

In [95]:
my_list
Out[95]:
[9, 999, 0, 8, 20]
In [96]:
my_list[-1:1:-1]
Out[96]:
[20, 8, 0]
In [97]:
my_list[:1:-1]
Out[97]:
[20, 8, 0]
In [98]:
my_list[-2::-1]
Out[98]:
[8, 0, 999, 9]

覚えておく価値があることは、 [: : -1] で中を逆順にしたリストのコピーが得られるということです:

In [99]:
my_list[::-1]
Out[99]:
[20, 8, 0, 999, 9]

タプル

タプルはリストとほとんど同じものです。ただしリストと異なりミュータブルでありません。つまり、タプルの要素も、要素の数も変更不可能です:

In [100]:
my_tuple = (9, 4, 7, 0, 8)
In [101]:
my_tuple
Out[101]:
(9, 4, 7, 0, 8)
In [102]:
my_tuple[1] = 99
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-102-0f927aac1466> in <module>
----> 1 my_tuple[1] = 99

TypeError: 'tuple' object does not support item assignment

これは空のタプルです:

In [103]:
empty_tuple = ()
In [104]:
empty_tuple
Out[104]:
()

2つの要素を持つタプルです:

In [105]:
two_tuple = (1, 5)
In [106]:
two_tuple
Out[106]:
(1, 5)

1つの要素でタプルを作るときには少し複雑なことがあります:

In [107]:
not_a_tuple = (1)
In [108]:
not_a_tuple
Out[108]:
1

これは、この式をかっこで囲まれた表現ではなくタプルとしたい、という意図をPythonが認識できないことによります:

In [109]:
not_a_tuple = (1 + 5 + 3)
In [110]:
not_a_tuple
Out[110]:
9

この式は長さ1のタプルとしたい、という意図をPythonに伝えるには、要素の後ろ、かっこ閉じの前にカンマを加えます:

In [111]:
one_tuple = (1,)
In [112]:
one_tuple
Out[112]:
(1,)

文字列

文字列はこのように作ります:

In [113]:
my_string = 'interesting text'
In [114]:
my_string
Out[114]:
'interesting text'

文字列については、シングルクォーテーションでもダブルクォーテーションでも使うことができ、どちらも同義です:

In [115]:
another_string = "interesting text"
In [116]:
another_string
Out[116]:
'interesting text'
In [117]:
my_string == another_string
Out[117]:
True

str を使って他のオブジェクトを文字列に変換します:

In [118]:
# 整数型を文字列に変換します
str(9)
Out[118]:
'9'
In [119]:
# 浮動小数点型を文字列に変換します
str(1.2)
Out[119]:
'1.2'

文字列はシーケンスである

リストと同様に、文字列はシーケンスです。つまり、長さを持ち、繰り返し可能で、インデックスが使え、スライスもできます:

In [120]:
# 長さを持つ
len(my_string)
Out[120]:
16
In [121]:
# 繰り返せる
for c in my_string:
    print(c)
i
n
t
e
r
e
s
t
i
n
g
 
t
e
x
t
In [122]:
# インデックスが使える
my_string[1]
Out[122]:
'n'
In [123]:
# スライスできる
my_string[1:5]
Out[123]:
'nter'

文字列は変更不可能である

リストと異なり、文字列はイミュータブルであり、変更不可能です。文字列内の文字は変更できません:

In [124]:
my_string[1] = 'N'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-124-ebca256d5213> in <module>
----> 1 my_string[1] = 'N'

TypeError: 'str' object does not support item assignment

文字列の結合

In [125]:
my_string + ' with added insight'
Out[125]:
'interesting text with added insight'

文字列のメソッド

文字列には、様々な興味深いメソッドが備わっています。Jupyter Notebookで、文字列の変数名の後にピリオドを打ってからタブ補完を試してみてください。例えば、 my_string. とタイプしてからタブキーを押します。Python docsにあるstring methodsのリストも見てみましょう。

興味深いメソッドのひとつに replace があります。このメソッドは入力した文字列のコピーを返しますが、文字列を別の文字列に置き換えてから返します:

In [126]:
another_string = my_string.replace('interesting', 'extraordinary')
In [127]:
another_string
Out[127]:
'extraordinary text'

オリジナルの文字列は変更されていない(変更不可能である)ことに注意しましょう:

In [128]:
my_string
Out[128]:
'interesting text'

文字列を分割してリストにするには、splitメソッドを使います。デフォルトでは、splitは文字列をあらゆる空白(スペース、タブ区切り、改行)で分割します:

In [129]:
my_string.split()
Out[129]:
['interesting', 'text']

ある文字で文字列を分割するには、その文字をsplitに渡します:

In [130]:
another_example = 'one:two:three'
In [131]:
another_example.split(":")
Out[131]:
['one', 'two', 'three']

stripメソッドは、文字列の最初と最後からスペース、タブ、行末文字を取り除いた文字列を返します:

In [132]:
# 文字列の最後に改行コードである\n をつけます
my_string = ' a string\n'
In [133]:
my_string
Out[133]:
' a string\n'
In [134]:
my_string.strip()
Out[134]:
'a string'

値の文字列への挿入

Inserting values into strings を参照してください。(訳注:別の文書のため、まだ訳されていません)

Range型

Python3において、 range は rangeオブジェクトを返します。rangeオブジェクトはシーケンスのため、かなりリストに似ています[4]。rangeで引数を1つのみ使うと、引数の値は終止インデックスとなります。例えば、0から5まで、しかし5を含まないようなrangeオブジェクトを作るには以下のようにします:

In [135]:
my_range = range(5)
In [136]:
my_range
Out[136]:
range(0, 5)

listを使うと rangeオブジェクトをリストに変換できます:

In [137]:
list(range(5))
Out[137]:
[0, 1, 2, 3, 4]

rangeオブジェクトはシーケンスです:

In [138]:
# 長さを持つ
len(my_range)
Out[138]:
5
In [139]:
# 繰り返せる
for e in my_range:
    print(e)
0
1
2
3
4
In [140]:
# インデックスが使える
my_range[1]
Out[140]:
1
In [141]:
# スライスできる
my_range[0:2]
Out[141]:
range(0, 2)

引数を2つ渡すと、rangeの開始要素を指定できます:

In [142]:
my_range = range(1, 7)
In [143]:
my_range
Out[143]:
range(1, 7)
In [144]:
list(my_range)
Out[144]:
[1, 2, 3, 4, 5, 6]

3番目の引数でステップサイズを指定できます:

In [145]:
my_range = range(1, 7, 2)
In [146]:
my_range
Out[146]:
range(1, 7, 2)
In [147]:
list(my_range)
Out[147]:
[1, 3, 5]

rangeをよく使う場面としては、forループで一連の数だけ繰り返す場合です:

In [148]:
for i in range(5):
    print(i)
0
1
2
3
4

セット

セットは順番が決まっていない要素の集まりです。要素の順番はPythonが決めます:

In [149]:
# セットでは要素は重複しません
my_set = set((5, 3, 1, 3))
In [150]:
my_set
Out[150]:
{1, 3, 5}

決まった順番がないので、セットにインデックスを付けることはできません:

In [151]:
my_set[1]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-151-d447519d8314> in <module>
----> 1 my_set[1]

TypeError: 'set' object does not support indexing

addメソッドでセットに要素を加えることができます:

In [152]:
my_set.add(10)
In [153]:
my_set
Out[153]:
{1, 3, 5, 10}

セットの要素は一意でなければならず、既にセット内にある要素を加えてもセットは変化しません:

In [154]:
my_set.add(5)
In [155]:
my_set
Out[155]:
{1, 3, 5, 10}

セットでも繰り返しはできますが、要素の順序は任意です。プログラムの2度の実行で同じ順序になるとは限りません:

In [156]:
# 要素の順番は決まっていません
for element in my_set:
    print(element)
1
10
3
5

difference, union, intersectionといった興味深い操作については、セットオブジェクトのメソッドを見てください。

セット、リスト、タプルはコンテナである

コンテナは要素に対し、そのコンテナに属しているかどうかを確かめることができるオブジェクトです。オブジェクトcがコンテナである場合、ある要素がそのコンテナに属しているかどうか、 要素 in c の結果が True か False かで確かめることができます。

注意してください。 inという単語はfor 要素 in c:true_or_false = 要素 in cとで違う意味を持ちます。for 要素 in c:では、inはforループ構文の一部です。true_or_false = 要素 in cでは、inは要素がコンテナに属しているかどうかを確認し、 True か False を返すトリガーとなっています:

In [157]:
5 in my_set
Out[157]:
True
In [158]:
11 in my_set
Out[158]:
False

要素がコンテナに入っていないことを確かめるには not in を使います:

In [159]:
11 not in my_set
Out[159]:
True

リストとタプルもコンテナです:

In [160]:
9 in [9, 4, 7, 0, 8]
Out[160]:
True
In [161]:
3 in (1, 3, 5)
Out[161]:
True

辞書

辞書は順序を持たず、「キー key」と「値 value」がペアになったものです。キーは要素を特定するもので、値は各キーに対応する値です:

In [162]:
# 空の辞書を作ります
software = {}

ここで、キーと値のペアを辞書に追加します。キーは文字列 'MATLAB' 、それに対応する値は整数の 50 です:

In [163]:
software['MATLAB'] = 50
In [164]:
software
Out[164]:
{'MATLAB': 50}

別のキーと値のペアを追加します:

In [165]:
software['Python'] = 100
In [166]:
software
Out[166]:
{'MATLAB': 50, 'Python': 100}

あるキーに対応する値は、辞書とキーを指定することにより取り出します:

In [167]:
software['Python']
Out[167]:
100

辞書でキーを取り出して繰り返し処理することができます。しかしキーの順序は一意ではありません。Pythonが決めた順序でキーを返します。そしてプログラム中で毎回同じ順序になるとは限りません:

In [168]:
for key in software.keys():
    print(key)
MATLAB
Python

値で繰り返し処理することもできますが、上記と同じく順序は一意ではないという制約があります:

In [169]:
for value in software.values():
    print(value)
50
100

キーと値のペアで繰り返し処理を行うには items メソッドを使います。この場合、要素は長さ2のタプルで、第1の要素がキー、第2の要素が値となります:

In [170]:
for key_value in software.items():
    print(key_value)
('MATLAB', 50)
('Python', 100)

辞書は中括弧を使っても作れます。コロンでキーと値を分け、コンマでペアを分けます:

In [171]:
software = {'MATLAB': 50, 'Python': 100}
In [172]:
software
Out[172]:
{'MATLAB': 50, 'Python': 100}

キーは重複があってはいけません。同じキーがあった場合、最初のキーと値のペアは、後のキーと値のペアで上書きされます:

In [173]:
software = {'MATLAB': 50, 'Python': 100, 'MATLAB': 45}
In [174]:
software
Out[174]:
{'MATLAB': 45, 'Python': 100}

辞書はコンテナである

辞書もコンテナです。Pythonはコンテナの要素をキーで取り出します。あるキーが辞書に含まれるかを確認するのは次の方法が便利でしょう:

In [175]:
'MATLAB' in software
Out[175]:
True
In [176]:
'happiness' in software
Out[176]:
False

“for”, “while”, “continue”, “break”

for文とwhile文はループです。for に指定した要素を全部使い切るか、 while 条件が False になるまで、Pythonは for や while のブロックを実行し続けます。break文を使ってループから抜けられます:

In [177]:
for i in range(10):
    if i == 6:
        break
    print(i)
0
1
2
3
4
5

continue文は、for や while ブロックにおいて、現在の繰り返し分の実行を切り上げ、次の繰り返しから再開します:

In [178]:
for i in range(10):
    if i == 6:
        continue
    print(i)
0
1
2
3
4
5
7
8
9

ループと break について更に詳しく知りたい場合は、 “for” and “while”, “break” and “else:” を参照してください。

関数

関数をPythonで作ってみます:

In [179]:
def my_function(an_argument):
    return an_argument + 1

関数の定義は、キーワード def と続いて半角スペース1つで始まります。関数名 my_function がその次に来ます。次に丸括弧と、関数に渡す引数の指定が続きます。今回の場合、関数が想定している引数は1個です。この関数では、実行開始時に入力された引数の値に an_argument という名前が付きます。最後に、関数が呼び出されたときに実行するコードのインデントブロックが来ます:

In [180]:
my_function(10)
Out[180]:
11

my_function に丸括弧で囲んだ引数を付けて呼び出します。関数は、変数 an_argument に10が代入された状態で実行されます。この関数は 10 + 1 = 11 を返します。

引数なしの関数もできます:

In [181]:
def my_second_function():
    return 42
In [182]:
my_second_function()
Out[182]:
42

return文がない関数もできます。return文がない場合、その関数はNoneを返します:

In [183]:
def function_with_no_return():
    # return文がない関数
    a = 1
In [184]:
function_with_no_return() == None
Out[184]:
True

複数の引数を受け入れる関数もできます:

In [185]:
def my_third_function(first_argument, second_argument):
    return first_argument + second_argument
In [186]:
my_third_function(10, 42)
Out[186]:
52

引数の初期設定値

関数を定義する際、引数に初期設定値を与えることができます:

In [187]:
def my_fourth_function(first_argument, extra_argument=101):
    return first_argument + extra_argument

この関数は my_third_function と同じく2個の引数を持ち、my_third_function と同じ呼び出し方ができます:

In [188]:
my_fourth_function(10, 42)
Out[188]:
52

一方、初期設定値があるので2番目の引数を省略することもできます。その場合、その引数には初期設定値が使われます:

In [189]:
my_fourth_function(10)  # 1番目の引数を渡し、2番めは初期設定値を使う
Out[189]:
111

これまでの例では、引数を順番で渡してきました。つまり、最初の引数が関数の第1引数となったわけです。引数は名前で渡すこともできます。たとえば、extra_argument を変数名と値で次のように渡せます:

In [190]:
my_fourth_function(10, extra_argument=202)
Out[190]:
212

引数をこの方法で渡すことはコードの可読性を向上させます。なぜなら、関数において引数名を見ればそれが何の目的で使われるのか手がかりになることがあるからです。多くの変数に初期設定値を与えることも有用です。その場合、引数名を使うことで、初期設定値と異なる一部の引数を渡すことが楽にできるようになります。

関数もオブジェクトである

Pythonではすべてがオブジェクトであることを覚えておいてください。関数もオブジェクトであり、関数名は変数で、その変数の型を調べると関数であることがわかります:

In [191]:
my_fourth_function
Out[191]:
<function __main__.my_fourth_function(first_argument, extra_argument=101)>
In [192]:
type(my_fourth_function)
Out[192]:
function

関数を呼び出す時は、関数名の後に丸括弧で囲まれた引数を付けます:

In [193]:
my_fourth_function(10)
Out[193]:
111

その他のPythonの変数と同様に、同じ関数を指す別の名前を簡単に作ることができます:

In [194]:
another_reference_to_func4 = my_fourth_function
In [195]:
type(another_reference_to_func4)
Out[195]:
function
In [196]:
# 関数を新たな名前で呼び出す
another_reference_to_func4(10)
Out[196]:
111

並べ替え Sorting

Pythonの sorted 関数は何かを並べ替えて、繰り返し処理が可能なリスト型にして出力します:

In [197]:
sorted('adcea')
Out[197]:
['a', 'a', 'c', 'd', 'e']
In [198]:
sorted((1, 5, 3, 2))
Out[198]:
[1, 2, 3, 5]

並べ替えの際、Python は ある要素 < 別の要素 で比較します。例えば、先ほどの並べ替えをするためにPythonは以下の結果を必要とします:

In [199]:
3 < 5
Out[199]:
True

要素を単に比較するのではなく、その他の方法でオブジェクトを並べたいこともあります。その場合、ソートするための関数を定義できます。この関数は、要素を引数として受け取り、並べ替えに用いられる値を出力します。Pythonは要素自体でなく、並べ替えに用いられる値を使って並べ替えを行います。

例えば、タプルとして並べたファーストネームと苗字があったとします:

In [200]:
people = [('JB', 'Poline'), ('Matthew', 'Brett'), ('Mark', 'DEsposito')]

デフォルトでは、Pythonはタプルをまず第1の値で比較、次に第2の値で比較、…というように比較します。今回の例の場合だと、ファーストネームの順に並ぶことになります:

In [201]:
('Matthew', 'Brett') > ('Mark', 'DEsposito')
Out[201]:
True
In [202]:
sorted(people)
Out[202]:
[('JB', 'Poline'), ('Mark', 'DEsposito'), ('Matthew', 'Brett')]

これは望んだ結果ではないかもしれません。タプルの第2の値である苗字で並べたい場合もあるでしょう。そのような場合、要素を入力(この場合はタプル)として受け取り、値(苗字)を出力する並べ替えのための関数を作れます:

In [203]:
def get_last_name(person):
    return person[1]  # 苗字を返す

Pythonではすべてがオブジェクトであることを思い出してください。今、定義したこの関数も、get_last_name という名のオブジェクトです:

In [204]:
get_last_name
Out[204]:
<function __main__.get_last_name(person)>

この値を並べ替えのために関数 sorted に渡すことができます。その際、key というパラメータを使って渡します。

In [205]:
sorted(people, key=get_last_name)
Out[205]:
[('Matthew', 'Brett'), ('Mark', 'DEsposito'), ('JB', 'Poline')]

ファイル

ファイルを異なるモードで開くことができます。モードによってファイルを読むか書くか、ファイル内のデータがテキスト(文字列)かバイナリ(バイト)かが決まります。例としてファイルを、テキストを書く(wt)ために開きます。 (訳注:"wt”モードで既存のファイルを開くと上書きされ元の内容は失われます。既存のファイルに追記する場合は"at”モードで開きます):

In [206]:
my_file = open("a_text_file.txt", "wt")

バイナリ(バイト)データを書く場合、モードは wb (Write Binary)を使います。通常、Jupyter notebook では オブジェクト名の後にピリオドをつけ (例えば my_file.)、そしてTabキーを押すと、この新規ファイルのアトリビュートやメソッドの一覧を表示することができます。

ファイルに書き込むには、write メソッドを使います:

In [207]:
# 文章を書き、最後に改行を意味する \n をつけます
# このメソッドは書かれた文字数を返します
my_file.write("MATLAB is good for matrices\n")
Out[207]:
28
In [208]:
# 別の行を追加します
my_file.write("Python is good for coding\n")
Out[208]:
26

終わったらファイルを close します:

In [209]:
my_file.close()

ファイルを読み込むときは、read モードで開きます:

In [210]:
# ファイルを読み込みモードで開きます
my_file2 = open("a_text_file.txt", "rt")

引数なしで read メソッドを呼び出すと、ファイルの内容をすべて読み込みます:

In [211]:
contents = my_file2.read()
In [212]:
print(contents)
MATLAB is good for matrices
Python is good for coding

後でファイルを close することを忘れないでください:

In [213]:
my_file2.close()

テキストファイルはイテラブル(繰り返し可能)であり、1行ずつ表示できます。for ループ内でファイルオブジェクトに内容を1行づつ出力させることもできます:

In [214]:
my_file2 = open("a_text_file.txt", "rt")
In [215]:
for line in my_file2:  # オブジェクト内の各行に対して繰り返します
    print("Line is:", line)
Line is: MATLAB is good for matrices

Line is: Python is good for coding

In [216]:
my_file2.close()

脚注

[1] Python 3では整数同士の割り算は浮動小数点で返されますが、Python 2では商の整数部分が返されます。そのためPython 2では、1 / 2 の結果は 1 // 2 の結果すなわち 0 と同じです。自作のコードを Python 2で使うときは、整数同士の割り算でPython 3と同じ結果になるように、 from future import division をソースコードファイルの最初に追加しておいて下さい。

[2]

Pythonのif文です:

In [ ]:
# Python
my_var = 10
if my_var == 10:
    print("The conditional is True!")
    print("my_var does equal 10")

同じものがRではこうなります:

In [ ]:
# R
my_var = 10
if (my_var == 10) {
    print("The conditional is True!")
    print("my_var does equal 10")
}

MATLABの場合:

In [ ]:
% MATLAB
my_var = 10;
if my_var == 10
    disp('The conditional is True!');
    disp('my_var does equal 10');
end

Pythonではインデントでブロックが決まります。RやMATLABでは、インデントはコードの見た目を良くするための意味合いしかありません。RやMATLABでは、インデントなしのコードは同じように動きますが、ほとんどの人は読みにくいと感じるでしょう:

In [ ]:
# R
my_var = 10
if (my_var == 10) {
# Indentation is optional
print("The conditional is True!")
print("my_var does equal 10")
}
In [ ]:
% MATLAB
my_var = 10;
if my_var == 10
% Indentation is optional
disp('The conditional is True!');
disp('my_var does equal 10');
end

[3]

これはPythonのループです:

In [ ]:
# Python
for element in [9, 4, 7, 0, 8]:
    print(element)

同じものがRとMATLABではこうなります:

In [ ]:
# R
for (element in list(9, 4, 7, 0, 8)) {
    print(element)
}
In [ ]:
% MATLAB
for element = {9, 4, 7, 0, 8}
    disp(e);
end

[4]

Python 2では、 range関数は list型を返します。 Python 3のrange型オブジェクトは大抵list型と同じように使えますので、おそらくコードを扱う側にとって Python 2 と 3 の違いは問題にならないでしょう。ただ、list型はできても range型ではできないもの(追加など)が存在します。例えば、 range(4) + range(5) は Python 2だと動きますが(listの結合)、Python 3だと失敗します(rangeオブジェクトは結合できません)。