初心者向けPython3勉強会:型


初心者向けPython3勉強会:型


諸注意


  • 本稿はJava(か、それ以外の言語)をかじっている同期に向けて、他言語とPythonの違いにフォーカスして作成しております

  • 作成にあたって、Python リファレンスをベースにしております

  • 初心者向けにチュートリアルも公開されております、詳細を理解しながら学習したい方にオススメです

  • Pythonはユニークな特徴をたくさん持っています。全て一度に説明すると取っ掛かりにくい部分もありますので、必要なものを必要なときに説明していきます

  • 執筆時のバージョンはPython 3.7.3です




はじめに

Pythonは「読みやすく、書きやすい」プログラミング言語です。そのため多くのユーザは、単純で短い簡潔コードをよしとする傾向が強いです

とはいえ、最初から簡潔なコードを目指すと苦労することが多々あります。なぜならば、Pythonは「読みやすく、書きやすい」プログラミング言語であるがために、独特な記法による記述が多いためです

以下に、はじめに気をつけるべきPythonの記法・性質について説明します



ブロックの記述方法

Javaなどでは、if文やfor文といったブロックを、中括弧{}で囲んで記述していたかと思います

Pythonでは中括弧は使わず、インデントを使用してブロックを記述します

このように、インデントが構文規則定められている規則を オフサイドルール と言います

詳しくはif文、for文の説明にの際に、併せて解説します



変数宣言

Pythonは 動的型付け(dynamic typing) を行う言語です

動的型付けとは、プログラムの実行時に型が決定されることを言います

Javaでは変数を宣言するたびに型を定義する必要がありましたが、Pythonではその必要はありません



オブジェクトと型の違い

Pythonでは、クラスも関数も変数も配列も型も、全てがオブジェクトです

とはいえ、最初からそれを意識しながら学習する必要はありません。なので、この章で扱うものは便宜上"型"と呼ぶことにします

(コメント欄でご指摘いただいている話はここにつながります、これに関しては後ほど説明します)



演算

Pythonでは他の言語と同じように、演算子や関数を用いてが様々な演算が行えます

今回は算術演算、ブール演算、比較演算の方法とその結果を紹介します


算術演算

演算
結果

+

-

*

/

//
切り捨て除算

%
剰余(除算の余り、mod)

**
累乗(x^y)

優先度は** > *, /, //, % > +, -になります

x, y = 10, 3

print("x + y =", x+y)
print("x - y =", x-y)
print("x * y =", x*y)
print("x / y =", x/y)
print("x // y =", x//y)
print("x % y =", x%y)
print("x ** y =", x**y)

# 出力結果
x + y = 13
x - y = 7
x * y = 30
x / y = 3.3333333333333335
x // y = 3
x % y = 1
x ** y = 1000



ブール演算

Pythonにおけるブール演算は、orandnotの3種類です

演算

or

and

not



比較演算

Pythonにおける比較演算子は以下の通りです

演算
意味

<
小なり

>
大なり

<=
小なりイコール

>=
大なりイコール

==
値が等しい

!=
等しくない

is
同一のオブジェクト

is not
異なるオブジェクト

in
含まれている

not in
含まれていない

isinの詳細については別稿で説明をします

また、Pythonでは比較演算子を連続して書けます

x = 10

y = 20

print(5<x<15)
# > True

print(10<y<=20)
# > True

print(20>(x+y)>10)
# > False



数値型


int型

整数を扱う型です。扱える値の範囲ですが、Pythonのintでは論理的な制限がありません

ただし、「確保可能なメモリサイズまで」といった物理制限はあります

shortやlongといった型もなく、Pythonにおける整数型が全てintで表現できます

x = 10

y = 20
z = a + b

print(z)
# > 30

z = 10**1000000
# print(z)とかすると、楽しいことになります



bool型

boolは真理値を扱う型です。TrueとFalseの2値をとります

Pythonにおいてboolはintの派生系で、Trueは1、Falseは0として扱われます

文字列に変換すると、TrueFalseといった形で表されます

Javaと違って、単語のはじめの文字が大文字になることに注意してください

x = 10

y = 20

print(x<y)
# > True

print(x>y)
# > False

z = True
print(z)
# > True

z = False
print(z)
# > True

z = True + True
print(z)
# > 2

z = True - True
print(z)
# > 0



float型

floatは小数を扱う型です

Javaで小数を表す場合は、floatかdoubleを用います、それぞれ32bit,64bitの浮動小数点数を扱う型です

Pythonではfloatが64bitの浮動小数点数になります。すなわち、doubleと同じです

a = 3.2

b = 6.4

print(a+b)
# > 9.600000000000001

print(a-b)
# > -3.2

print(a*b)
# 20.480000000000004

print(a/b)
# > 0.5



complex型

複素数型です、実部と虚部はそれぞれfloatで表現されます

.real,.imagを用いることにより、実部と虚部をそれぞれ抜き出すことができます

a = 2+1j

b = 3-4j

print(a+b)
# > (5-3j)

print(a-b)
# > (-1+5j)

print(a*b)
# > (10-5j)

print(a/b)
# > (0.08+0.44j)

print(a.real, b.imag)
# > 2.0 -4.0



コンテナオブジェクト

str,list,tuple,dict,rangeは、コンテナオブジェクトと呼ばれ、複数のオブジェクトをまとめることができます

Javaでいう配列やリストがこれにあたります。ただし、Javaの配列と違い、動的確保をすることができます

list[]tuple()dict{}、でそれぞれ定義できます


動的確保 :配列などを宣言する際に、変数などを用いて宣言する方法です

変数の値に応じて配列の大きさを設定できます




str型

String型です、配列としても扱うことができます

Pythonにはchar型が存在しないので、String型の文字列は、1文字のString型による配列として表現されます

また、+で文字列の結合を行うことができます

シングルクォーテーションかダブルクォーテーションで囲うとString型になります、クォーテーションによる区別はありません

ただし、String宣言時とは異なるクォーテーションを文字列に含める場合、エスケープせずに出力することができます


JavaではString型はダブルクォーテーションで表現されます

そのため、文字列の中にダブルクォーテーションがあると、正しく出力されません

ダブルクォーテーションを出力したい場合は、エスケープをすることによって、文字列として扱うことができます

大概、エスケープしたい文字の前にバックスラッシュを置けばエスケープできます

例:System.out.println("Rafaelは\"Hello, world!\"と声高らかに叫んだ")

  > Rafaelは"Hello, world!"と声高らかに叫んだ


text = 'Hello, world!'

print(text)
# > Hello, world!

print(text + ' Good night!')
# > Hello, world! Good night!

print("Rafaelは\"Hello, world!\"と声高らかに叫んだ")
# > Rafaelは"Hello, world!"と声高らかに叫んだ

print('Rafaelは"Hello, world!"と声高らかに叫んだ')
# > Rafaelは"Hello, world!"と声高らかに叫んだ



list型

listはコンテナオブジェクトの中でも最もシンプルな型です、ミュータブルなシーケンス型で、中に格納される値は型が違っても問題ありません


ミュータブル :定義したあとでも値が変えられる

シーケンス型 :配列や文字列など、順番のある要素の集まり


中に格納された値を要素、要素が格納されている場所を指す値を添字(インデックス)と呼びます

添字は基本的に前から数えた順番で表現しますが、負の値を用いた場合、後ろから数えた順番になります

line = [0,1,2,3,4,5]

print(line)
# > [0,1,2,3,4,5]

print(line[2])
# > 2
print(line[-2])
# > 4

line[3] = 10
print(line)
# > [0,1,2,10,4,5]

line = ['apple', 'banana', 'chocolate']

print(line)
# > ['apple', 'banana', 'chocolate']
print(line[1])
# > banana
print(line[-1])
# > chocolate

line = [2019, '年', 5, '月', 1, '日']
print(line)
# > [2019, '年', 5, '月', 1, '日']

listはスライス操作が使えます


line[start:goal]と書くと、i以上j未満の要素を取り出すことができます。このとき、iまたはjは省略することが可能です

また、拡張スライス操作といった機能もありますが、別稿で説明をします

line = [0,1,2,3,4,5]

print(line)
# > [0,1,2,3,4,5]

print(line[1:4])
# > [1,2,3]

print(line[2:])
# > [2,3,4,5,6]

print(line[:3])
# > [0,1,2]

print(line[:])
# > [0,1,2,3,4,5]

listの扱いについては、for文や内包表記を説明する際に併せて説明します



tuple型

tupleはイミュータブルなシーケンス型です、listがイミュータブルになった、というイメージで今は問題ありません


イミュータブル :定義したあとに値が変更できない


vect = (3, 6)

print(vect)
# > (3, 6)

print(vect[1])
# > 6

vect[1] = 4
# > Traceback (most recent call last):
# > File "<stdin>", line 1, in <module>
# > TypeError: 'tuple' object does not support item assignment



dict型

dictはミュータブルなマッピング型です


マッピング型 :キーと値が対応づけられている配列、ディクショナリー配列、連想配列とも呼ばれる


listやtupleと違い、要素をkeyvalueで紐づけます。keyが添字、valueが値です


また、辞書・連想といった単語からわかるように、dictはkeyからvalueを取り出すことができます

price = {'apple':80, 'banana':120, 'chocolate':100}

print(price['apple'])
# > 80

print(price['chocolate'])
# > 100

price['water'] = 70
print(price['water'])
# > 70

また、dictではkeyが添字となるため、keyはイミュータブルであるべきです

よって変数などをkeyとして使用しないことが望まれます

valueではそのような制約はないですが、少し複雑な構成になります

fruit = 'banana'

v = 80
price = {'lemon':v, 'water':60, fruit:120}

print(price['lemon'])
# > 80

v = 100
print(price['lemon'])
# > 80

print(price[fruit])
# > 120

fruit = 'apple'
print(price[fruit])
# > Traceback (most recent call last):
# > File "<stdin>", line 1, in <module>
# > KeyError: 'apple'

valueに変数を使用し後から値を変更すると、dictに結果が反映されます、これはdict['lemon']に直接vが入っているためです

しかしfruitの変更は容認されません

これはfruit = 'banana'よりfruit:120'banana':120と置き換えられるからです

そのため、fruit = 'apple'と代入してしまうと、price[fruit]price['apple']に置き換えられ、keyが存在しないためエラーとなってしまいます



range

rangeはイミュータブルなシーケンス型で、主にfor文などのループに使われます

整数の等差数列のリストを生成することができる組み込みメソッドです

range(i,j)と書くと、listのスライス操作と同じように数列を表現できます

また、最初の値(上例ではi)を省略すると自動的に0が代入されます

# range自体はメソッドなので、中身を見たい場合はlistにキャストします

print(list(range(0,10)))
# > [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(list(range(10)))
# > [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(list(range(4,12)))
# > [4, 5, 6, 7, 8, 9, 10, 11]

また、rangeは拡張スライス操作と同じようにステップ数も設定できます


おわりに

以上が、Pythonで一般的に使われる型の説明です

今回は型の性質を説明するため話をだいぶ省略していますが、Pythonらしい面白い機能がたくさん備わっています

特にコンテナオブジェクトでは、内包表記といったPython独自の記述方法があります、是非覚えていきましょう!

また、本稿について不明点・修正点などございましたら、何卒コメントをよろしくお願いいたします


人生苦短我用Python!!