Python/
Pythonは高水準の汎用プログラミング言語です。 Pythonの設計思想はコードの読みやすさに重点を置いています。 その構造に対するアプローチは独特であり、例えば、ブロックは波括弧 { } ではなくインデントで構造化されています。
また、Pythonはオブジェクト指向、インタプリタ、動的コーディング、クロスプラットフォームのプログラミング言語です。 これらのアプローチは、プログラマが小規模なプロジェクトから大規模なプロジェクトまで、自明で論理的なコードを書くことができるようにすることを目的としています。
基本事項[編集]
開発環境[編集]

Pythonは、UnixやGNU/Linuxのディストリビューション、macOSには最初から付属していますが、その他のオペレーティングシステムでは、当初Pythonがインストールされていない場合があります。
GNU/Linuxのデスクトップ環境では、コマンドターミナルを起動し、コマンドターミナルで「python」というコマンドを実行すると、インターラクティブモードで起動します。
$ python Python 3.11.0 (main, Oct 29 2022, 01:12:10) [Clang 15.0.2 ] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
「>>> 」のあとに、キーボードによって文字を入力をします。「>>> 」をプロンプトといいます。
なお、pythonのこのような入力モードを、「インタラクティブ モード」といいます。
インタラクティブ モードを終了したい場合は、コマンド「exit()」を実行します。
WindowsでのPythonのプログラミング[編集]
Microsoft Windowsの場合:
- 公式配布版Pythonインストーラ(英文)を使用し導入する。
- Microsoft Storeから Python を導入する。
の2通りの導入方法があります。
pythonの実行方法[編集]
Pythonの実行方法には、大きく分けて2つあります。
- インタラクティブモードでの実行方法
- ソースファイルを作成して実行する方法
インタラクティブモードでの実行方法[編集]
インタラクティブモード(REPL: Read-Eval-Print Loop)では、Pythonのコマンドを1行ずつ入力して実行することができます。
以下の手順で実行してください。
- ターミナルを開きます。
- "python"と入力します[1]。
- ">>>"プロンプトが表示されますので、Pythonのコマンドを1行ずつ入力して実行します。
例えば、"print('Hello World')"と入力すると、"Hello World"と出力されます。
ソースファイルを作成して実行する方法[編集]
ソースファイルを作成する場合は、以下の手順で実行してください。
- テキストエディタを開きます。
- Pythonのプログラムを入力し、ファイル名を"*.py"で保存します(例:"hello.py")。
- ターミナルを開き、以下のコマンドを入力します[1]。
$ python ファイル名.py
- ソースファイルが実行されます。
- 例えば、以下のようなPythonプログラムを"hello.py"というファイル名で保存し、
- hello.py
print("Hello World")
- 実行する場合は[1]、
$ python hello.py
- と入力して実行します。
- Pythonのソースファイルは、拡張子が"py"になります。
ソースコードだけを書換えてみる[編集]
では、さきほどの「Hello World」と表示するプログラムを実行してメッセージ表示させた直後に、
ソースコードだけを書換えてみると、どうなるのでしょうか。
さきほどの「Hello World」と表示するプログラムを実行してメッセージ表示させた直後に、ソースコードのファイル「hello.py」に
print("12345Hello World")
と入力して、さきほどのソースコードのファイル「hello.py」に上書き保存したら、どうなるでしょうか?
「hello.py」で保存した直後に、 コマンドターミナルで
$ python hello.py
を実行すると、
12345Hello World
と表示されます。
つまり、pythonでは、コマンド python hello.py
を実行するたびに、ソースコード(この場合は「hello.py」がソースコード)を解釈しなおします。
「Pythonはインタプリタ言語である」ということは、先述の例のように、プログラムを実行するたびにソースコードを解釈し直すということを意味しています。
数値の計算[編集]
Pythonでは、数値の四則演算が簡単に行えます。足し算には「+」を、引き算には「-」を、かけ算には「*」(アスタリスク)を、割り算には「/」(スラッシュ)を使用します。
例えば、2つの数値を足す場合は、「2 + 3」というように入力します。Pythonは自動的に答えを計算し、結果を表示します。同様に、引き算、かけ算、割り算も同じように行えます。
インタラクティブモードでは、コマンドターミナルでPythonを起動し、コマンドラインで1行ずつコードを入力できます。
例えば、ターミナルで「python」と入力すると、Pythonインタープリターが起動し、インタラクティブモードでコードを入力できます。このモードでは、Pythonコードを逐次実行できます。
では、計算をためしてみましょう。
>>> 2+3 5
>>> 6+7 13
浮動小数点数の計算も行えます。
>>> 30.6 + 7.1 37.7
>>> 5-4 1
>>> 23.88 - 7.5 16.38
負数の計算もできます。
>>> 2-15 -13
>>> 2*4 8
>>> 4/2 2.0
>>> 4/3 1.3333333333333333
インタラクティブ モードを終了するには、「exit()」を入力します。
exit() %
Pythonでは、整数と浮動小数点数を足したり引いたりする場合、自動的に浮動小数点数に変換して計算します。
例えば、整数の2と浮動小数点数の1.5を足す場合、「2 + 1.5」というように入力します。Pythonは自動的に2を2.0に変換し、計算を行います。同様に、浮動小数点数と整数の引き算も自動的に浮動小数点数に変換されます。
この仕組みは、Pythonのデータ型が動的に変更されるという特徴によるものです。Pythonでは、変数に代入された値に応じてデータ型が自動的に変更されます。 例えば、整数値が代入された変数に浮動小数点数値を代入すると、その変数のデータ型が自動的に浮動小数点数型に変換されます。このため、整数と浮動小数点数の計算も自動的に適切なデータ型に変換されて計算されます。
割り算の商だけを求めたい場合、「//」を使います。 例えば、「10 // 3」という計算を行うと、商の「3」が得られます。
この演算子は、小数点以下の値を切り捨てて、整数部分の商を求めます。 例えば、「-10 // 3」という計算を行う場合、商は「-4」となります。
一方、「/」演算子は、通常の割り算を行い、結果として小数点以下の値も含めた浮動小数点数を返します。
Pythonの除算演算子には、このように「//」と「/」の2つがあり、それぞれの目的に合わせて使い分けることが重要です。
Pythonには、べき乗演算を行うための ** 演算子があります。例えば、「2**3」という計算を行うと、「8」という結果が得られます。
この演算子は、左辺を底とし、右辺を指数とした累乗を計算します。また、負の指数を用いることもできます。例えば、「2**-3」という計算を行う場合、逆数の計算をして、「0.125」という結果が得られます。
このように、「**」演算子を使用することで、数値を効率的に累乗することができます。
3項以上の計算[編集]
3Pythonでは、3項以上の計算も可能です。複雑な計算式を書く場合は、演算の優先順位にも注意が必要です。
たとえば、「2 + 3 * 4」という式を計算する場合、「3 * 4」が先に計算されてから、「2 + 12」が計算されます。結果として、「14」という値が得られます。
演算子には、優先順位を決める規則がありますが、括弧を使用することで、明示的に優先順位を指定することもできます。
変数と代入[編集]
変数とは[編集]
pythonでいう「変数」(へんすう)とは、値につけられた名前(識別子)です。
- コード例
a = 5 b = a + 2 print(b)
- 実行結果
7
- aやbが変数です。変数aには値5が入っています。変数bには値7(=5+2)が入っています。
型[編集]
ここまでの例では、代数学の「変数」と、プログラミングの「変数」とは、似ているところもありますが違う意味論を持ちます。 Pythonでは変数には文字列のように数値以外とも結びつけること(バインディングすること)ができます[2]。 このため代数学でいう「変数」と、プログラミングでいう「変数」との意味の違いに気をつけてください。
Pythonでは変数には型がなく、変数にバインディング(束縛)されたオブジェクトに型があります[3]。
- 整数型 — 0, 1, 2, -123, 100, 10000
- 実数型 — 0.0, -12.2, 1.2, 10e19
- 文字列型 — "", "abc", "かな漢字"
- リスト型 — [], [1, 2, 3], [1, 2, "a", [34, 89], ]
などがあります。
- 変数には型がなくオブジェクトに型がある
a = 1 print(a) a = "XYZ" print(a)
- 実行結果
1 XYZ
- 変数aの値は、2行目までは 1(整数)でしたが、3行目で "XYZ"(文字列)となっています。
- 2行目までと3行目以降とでは、変数aにバインディングされたオブジェクトが整数から文字列に変わったことを示しています。
- このようにPythonのような動的型付け言語では、変数は「値を入れる箱」ではなく「オブジェクトに(一時的に)つけられた名前、あるいはオブジェクトと名前のペア」です[4]。
- 2つ以上の変数が同じオブジェクトにバインディングされた例
a = [] print(f"{a=}") b = a print(f"{a=}, {b=}") b.append(100) print(f"{a=}, {b=}")
- 実行結果
a=[] a=[], b=[] a=[100], b=[100]
- aに空の配列を代入
- aの値をprint ⇒ a= []
- bにaを代入
- aとbの値をprint ⇒ a= [] , b= []
- bの要素に100を追加
- aとbの値をprint ⇒ a= [100] , b= [100] — 変更してのはbなのにaも同じ様に変更されている — 同じ配列にバインディングされている
- f"{a=}, {b=}" は、フォーマット済み文字列リテラルです。変数や式の値を確かめるのに便利です。
代入[編集]
pythonでは「=
」記号は、「左辺の識別子に右辺のインスタンスをバインドする」ことを意味します。
数学の等号とはもちろん、静的型付けの言語の代入とも意味が違いますが、Pythonを含む動的型付けな言語ではこれを代入と呼びます。
- コード例
a = 3 a = a + 1 print(a)
- 実行結果
4
- 1行目の
a = 3
」によって、まず、aに3が代入されます。 - 2行目の
a = a + 1
」では、まず右辺の評価が先に行われるので、変数aの値3が参照され 3+1 が評価され、その結果が左辺に代入されます。よって、aの値が4に置き換わります。
二文字以上の変数名[編集]
変数名はべつに1文字でなくてもかまいません。
- コード例
abc = 6 xyz = abc + 4 print(xyz)
- 実行結果
10
- abcやxyzが、変数です。
変数には意味のある名前をつけましょう[編集]
変数の名前には、そのプログラムの使い道にもとづいた名前をつけると、わかりやすくなります。
- コード例
price = 800 pics = 3 cost = price * pics print(cost)
- 変数名から、「単価が800円のモノを3個の値段」と、見ただけで予想がつきます。
識別子とキーワード[編集]
識別子[編集]
pythonでは、識別子の大文字と小文字とを区別します。 このため、たとえば「print("ABC")」を「PRINT("ABC")」と書くと、エラーになり実行できません。 また、変数名や関数名などの識別子につかえる文字として、英数字とアンダースコア「_」が、識別子として使用できます。 ただし、識別子の先頭の一文字には数字は使えません。
- コード例
A = 1 a = 3 print("A=", A) print("a=", a)
- 実行結果
A= 1 a= 3
識別子に使えるASCII範囲外の文字 |
Python3.0からは、識別子にASCII範囲外の文字の一部が使えるようになりました[5]。
識別子に使えるコード:
ASCII範囲外の文字も識別子に使えるようになったものの、表示や編集に支障がある環境のことや正規化に関するトラブルに配慮するなら、識別子はASCIIの範囲内に留めるのが良いでしょう。 |
キーワード[編集]
キーワード(Keywords)は、Pythonの構文規則の中に現れる特別なトークンで、識別子の様式に合致するにも関わらず、識別子には使用できない単語の集合です[6]。 次に示すキーワードは識別子には使用できません[7]。
- キーワードの一覧を表示するスクリプト
import keyword print(' '.join(keyword.kwlist))
- 実行結果
False None True and as assert async await 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
ソフト・キーワード[編集]
ソフト・キーワード(Soft keywords)は、識別子の中で、特定の状況下でのみ予約されるものです[8]。 識別子 match、case、_ は、パターン・マッチング文に関連する文脈では、構文的にキーワードとして機能しますが、この区別はトークン化の際ではなく、パーサー・レベルで行われます。 ソフトキーワードであれば、match、case、_を識別子名として使用している既存のコードとの互換性を保ちつつ、パターン・マッチングで使用することができます。
予約済み識別子クラス[編集]
予約済み識別子クラス(Reserved classes of identifiers)[9]は、キーワードやソフト・キーワード以外の識別子で特別な意味を持つものです[10]。 予約済み識別子クラスは、先頭と末尾のアンダースコア文字のパターンによって識別されます。
- _*
- from module import * でインポートされていません。
- _
- match文の中のcaseパターンでは、_はワイルドカードを表すソフトキーワードです。
- これとは別に、対話型インタープリタでは、最後に評価した結果を変数 _ に格納して利用できるようにしています(これは、print などの組み込み関数と一緒に builtins モジュールに格納されています)。
- その他の場所では,_は通常の識別子です.これはしばしば「特別な」アイテムの名前に使われますが、Python自体にとっては特別なものではありません。
- Note
- _ はしばしば国際化に関連して使用されます。この慣習についての詳細は gettext モジュールのドキュメントを参照してください。
- また、使われていない変数にもよく使われます。
- __*__
- システムで定義された名前で、非公式には "dunder "名として知られています。これらの名前は、インタープリタとその実装(標準ライブラリを含む)によって定義されます。現在のシステム名については、「特別なメソッド名」のセクションなどで説明しています。Pythonの将来のバージョンでは、さらに多くの名前が定義されるでしょう。明示的に文書化された使用方法に従わない、いかなる文脈での
__*__
名の使用も、警告なしに破壊される可能性があります。 - __*
- クラスプライベートな名前です。このカテゴリの名前は、クラス定義の文脈の中で使用された場合、基底クラスと派生クラスの "private "属性の間の名前の衝突を避けるために、マングルされたフォームを使用するように書き直されます。
アトム[編集]
アトムは、式の最も基本的な要素です。最も単純なアトムは、識別子またはリテラルです。括弧や大括弧、中括弧で囲まれた形式も、構文上はアトムに分類されます[11]。
識別子(名前)[編集]
アトムとして出現する識別子は名前です[12]。
名前がオブジェクトにバインドされている場合、アトムを評価するとそのオブジェクトが得られます。名前がバインドされていない場合、評価しようとすると NameError という例外が発生します。
- プライベート名のマングリング。
- クラス定義に含まれる識別子が、2つ以上のアンダースコアで始まり、2つ以上のアンダースコアで終わらない場合、そのクラスのプライベート名とみなされます。プライベート・ネームは、コードが生成される前に長い形式に変換されます。この変換では、クラス名の前に、先頭のアンダースコアを削除し、1つのアンダースコアを挿入します。例えば、Hamという名前のクラスで発生した識別子__spamは、_Ham__spamに変換されます。この変換は、識別子が使用されている構文上の文脈とは関係ありません。変換後の名前が極端に長い(255文字以上)場合は、実装で定義された切り捨てが行われることがあります。クラス名がアンダースコアだけで構成されている場合、変換は行われません。
組込み関数や、組込み型はキーワードではありません[編集]
組込み関数(例えば print)や、組込み型(例えば int)はキーワードではありません。 キーワードではありませんが、迂闊に組込み関数や組込み型と同じ名前の変数や関数を定義すると、次から関数が使えなくなります。 回避方法はあります。
- コード例
p=print print=123 p(print)
- 実行結果
123
- printを123で代入し参照不能に陥る前に、pに(実行結果でなく)print関数を代入しています。
- 関数呼び出しは、保存した p を介して行っています。
回避方法はあるものの、読んだヒト[13]が混乱するので組込み関数や型と重複した識別子は使わないように心がけましょう。
参考文献[編集]
- “3.10.0 Documentation » The Python Language Reference” (2021年11月29日).テンプレート:Cite web/error
- “3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3. Identifiers and keywords” (2021年11月29日).テンプレート:Cite web/error
- “3.10.0 Documentation » The Python Language Reference » 6. Expressions§6.2. Atoms” (2021年11月29日).テンプレート:Cite web/error
数値入力と文字入力と出力表示[編集]
入力[編集]
文字列の入力[編集]
文字列の入力には、組込み関数input()を使います。
x = input("文字を入力してみよう。") print(2 * x)
文字を入力してみよう。 a aa
- たとえば
a
と入力すると、aa
が出力されます。 abc
と入力すると、abcabc
が出力されます。
なお、数字(1
や2
など)を入力しても、文字として認識されます。
たとえば上のプログラムの実行で1
を入力すると、出力は11
となります(文字列の乗算演算子は文字列をオペランドの個数分繰返した文字列を返します)。
数値の入力と計算[編集]
では、数値を入力させて、計算をさせたい場合、どうすればい良いのでしょうか?
文字列から整数への変換[編集]
s = input("数値を入力してください。2倍にします。") n = int(s) print(2 * n)
- 上記のコードを実行すると、数字の入力を求められますので、たとえば4と入力してエンターキーを押すと、
8
が表示されます。自動的に2倍にした数字(4
と入力た場合は8
)が表示されます。 - int()により、入力された文字列を数値(整数)に変換します。intは、整数(integer)の略です。
- 上のプログラムで求められる入力に、
2.7
のような小数点の数を入れるとValueError例外があがります。 ValueError: invalid literal for int() with base 10: '2.7'
文字列から浮動小数点数への変換[編集]
文字列を浮動小数点数の数値を得たい場合は、組込み関数float()を使います。
s = input("数値を入力してください。2倍にします。") n = float(s) print(2 * n)
- 上のプログラムに、
2.7
を入力すると、5.4
が表示されます。 - 上のプログラムで求められる入力に、
2.7a
のような小数点の数を入れるとValueError例外があがります。 ValueError: could not convert string to float: '2.7a'
文字列入力と例外処理 |
input関数で得た文字列は(人間が自由に入力したものなので)、int関数やfloat関数が想定する形式ではない場合があり、そのときはValueError例外があがります。
この他、input関数がEOF(End of File; ファイルの終端)に達するとEOFError例外があがります。 例外を捕捉しないと、プログラムは異常終了してしまいます。
|
変数と文字列を同時に表示したい場合[編集]
s = input("文字列を入力してみてください。") print(s, "が入力されました。")
- print関数の表示で、変数(上例の場合は、sが変数)と文字を一緒に表示したい場合は、たとえば上記のコードのように、「,」(カンマ)で区切って、一緒に表示することができます。
さきほどの数値の入力と計算プログラムを、この方法で、書き換えましょう。
s = input("数字を整数で入力してみよう。(入力値をiと表示します。) 2倍にするよ。") i = int(s) print(f"{i=}, {2 * i=}")
これを実行して、たとえば「5」と入力してエンターキーを押すと、出力として i=5, 2 * i=10 と表示されます。
フォーマット済み文字列リテラル[編集]
Python には文字列の中に式を埋込み文字列化する「フォーマット済み文字列リテラル(Formatted string literals; F文字列とも)」があります[14]。
print(f"文字列の中に{ 式 }を埋め込むことができる")
のように、fを引用符の前につける事で利用できます。 引用符は二重引用符でも一重引用符でも、どちらでも構いません(ただし、引用符の開始と終始における引用符の種類は一致している必要があります。)。 JavaScriptなどの「テンプレート・リテラル」に相当する機能です[15]。
- コード例
x = 123 print(f"数は{x+100} です")
- 実行結果
数は223 です
F文字列は Pyhon3.6 から導入されました。Python2.x系では利用できません[16]。
'{' と '}' 自身の文字列中での使用[編集]
場合によってはテンプレートリテラルを使いつつも '{' や '}' 自身を文字列中で使用したい場合があります。 その場合は、'{' は '{{'、'}' は '}}' と二重にします。
- コード例
x = 123 print(f"文字列{{x}} には {x} が代入されます")
- 実行結果
文字列{x} には 123 が代入されます
{式=} :式と値の双方の文字列化[編集]
式の後に等号'='を付けることで式のテキストと評価後の値の両方を文字列化することができます。
- コード例
x = 123 print(f"式と値の表示:{x=}") print(f"式と値の表示:{[x * 2 for x in range(5)]=}") print(f'''\ +++ {x=} *** {[x * 2 for x in range(5)]=} ''')
- 実行結果
式と値の表示:x=123 式と値の表示:[x * 2 for x in range(5)]=[0, 2, 4, 6, 8] +++ x=123 *** [x * 2 for x in range(5)]=[0, 2, 4, 6, 8]
- ''' から ''' あるいは、""" から """ はヒアドキュメントで、複数行に渡る文字列を表現できます。
- ヒアドキュメントに f あるいは F を前置すると、Fヒアドキュメントになり、式の埋め込みができます。
- 開始を、 '''\ の様に \ を後置すると最初の改行を抑止できます。
Pythonの文字列フーマッティングの歴史[編集]
文字列の%演算子[編集]
最初に、文字列の % 演算子がありました。
x = 333 print('数は %s です' % x )
- 実行結果
数は 333 です
文字列のformatメソッド[編集]
次に、文字列のformatメソッドができました[17]。
x = 200 print('数は{y} です'.format(y=x) )
- 実行結果
数は200 です
脚註[編集]
- ^ 1.0 1.1 1.2 Pythonのコマンド名は環境によって異なります。
- ^ リスト、タプル、辞書については後で取り扱います。
- ^ “3.10.0 Documentation » The Python Language Reference » 4. Execution model§4.2. Naming and binding” (2021年11月29日). 2021年11月30日閲覧。
- ^ C言語/C++/Javaの様な静的型付け言語では、変数は「値を入れる箱」で変数は名前と一対一なアドレスを持ちます(変数がレジスターに割付けられた場合は例外です。この場合も変数名(=識別子)とオブジェクトの間の一意性はあります)。
- ^ “PEP 3131 -- Supporting Non-ASCII Identifiers” (2007年5月1日).テンプレート:Cite web/error
- ^ “keyword — Testing for Python keywords” (2021年11月29日).テンプレート:Cite web/error
- ^ “3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3.1. Keywords” (2021年11月29日).テンプレート:Cite web/error
- ^ “3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3.2. Soft Keywords” (2021年11月29日).テンプレート:Cite web/error
- ^ Reserved classes of identifiersを「予約済み識別子クラス」と訳しました。ここで言うクラスはオブジェクト指向プログラミングでいう Class ではなう階級や種類という一般的普遍的な意味のクラスです。
- ^ “3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3.3. Reserved classes of identifiers” (2021年11月29日).テンプレート:Cite web/error
- ^ “3.10.0 Documentation » The Python Language Reference » 6. Expressions§6.2. Atoms” (2021年11月29日).テンプレート:Cite web/error
- ^ “3.10.0 Documentation » The Python Language Reference » 6. Expressions§6.2.1. Identifiers (Names)” (2021年11月29日).テンプレート:Cite web/error
- ^ 将来のあなたかもしれません。
- ^ “Lexical analysis # Formatted string literals” (2021年11月29日). 2021年11月29日閲覧。
- ^ JavaScriptのテンプレート・リテラルはヒアドキュメントの機能も持っています。
- ^ Python2.x系のサポートは2021/01/01に終了しました。 ⇒ PEP 373 -- Python 2.7 Release Schedule, PEP 404 -- Python 2.8 Un-release Schedule
- ^ PEP 3101 -- Advanced String Formatting
条件分岐と繰り返し[編集]
Python の制御構造には、逐次・分岐・繰返しの3つがあり。このうち逐次はプログラムが左上から左から右・上から下に進む当たり前の状態ですので、これ以上の説明は必要ないと思います[1]。
条件分岐[編集]
条件分岐とは、ある条件を満たすかどうかで、次に実行するプログラムの位置を変えることです。
if文[編集]
最も素朴な条件分岐は、単一のif文です[2]。
- if文による条件分岐
x = 3 if x == 2 : print("abcd")
- 条件分岐の上のコードの、
x == 2
とは、「xは2に等しい」という意味です。 - 冒頭の「x = 3」は、xに3を代入するという意味です。
- python では、if文にある条件式にある等号と、代入との等号を区別するために、条件分岐での等号には
x == 2
を使います。 - 上のコードでは、「xは2に等しい」の条件を満たさないため(xには3が代入されています)、実行しても文「abcd」は表示されません。
- また、pythonでは、if文の中の文(ブロックと言います)は、字下げをします(この様なインデントによる構造構文をオフサイドルールと言います)。
- インデントは半角スペース4つが推奨されます。
- 実行結果
※なにも表示されません。
つぎに、if文のなかのxの条件を変えてみて、条件が成り立つようにしましょう。
- 条件が真になるように変更
x = 3 if x == 3 : print("abcd")
- 上のコードでは、「xは3に等しい」の条件を満たすので、実行したら文「abcd」が表示されます。
- 実行結果
abcd
つまり、if文の構文は、次のようになります。
if 条件式 : 処理
- if文のブロックの外に文を追加
x = 3 if x == 2 : print("abcd") print("ef")
上のコードでは、print("ef")はif文のブロックの外にあることになります。 なぜなら、print("ef")は字下げされてないからです。 なので、プログラムを実行すると「ef」が表示されます。
いっぽう、次のコードでは、結果が変わります。
- if文のブロックに文を追加
x = 3 if x == 2 : print("abcd") print("ef")
上のコードでは、print("ef")はif文ブロックの中にあるので、プログラムを実行しても、「ef」は表示されませんし、もちろん「abcd」も表示されません。
ifブロック内は、字下げをそろえないと、エラーになります。
- インデントに誤りのある例
x = 3 if x == 2 : print("abcd") print("ef")
(↑エラーになります。)
下記コードでは、x==2
が満たされていないので、インデントされたブロックは実行されません。そのため実行すると「プログラムが終了しました。」だけが表示されます。
x = 3 if x == 2 : print("abcd") print("ef") print("プログラムが終了しました。")
条件式には、不等号(>
や<
など)も使えます。
x = 3 if x > 2 : print("xは2よりも大きい。") print("プログラムが終了しました。")
上のコードを実行すると「xは2よりも大きいよ。」と「プログラムが終了しました。」が表示されます。
比較演算子[編集]
記号>
のような、値を比較する演算子のことを比較演算子といいます。
pythonで使える比較演算子には、次の表のようなものがあります。
比較演算子 演算子 意味 >
左側の数が、右側の数よりも大きい <
左側の数が、右側の数よりも小さい ==
両辺の数値の大きさが等しい !=
等しくない >=
左側の数が、右側の数よりも大きいか、
または両辺が等しい<=
左側の数が、右側の数よりも小さいか、
または両辺が等しい
in 演算子[編集]
in 演算子は、オブジェクトがコレクションの要素にあるかを返します。
- in 演算子
li = [2,3,5] tu = (10,20,30) print(2 in li) print(2 in tu)
- 実行結果
True False
else節のあるif文[編集]
前の節では、if文の条件式によってブロックの実行/否を切り替えました。 ここでは、一歩進めて条件式に合致していなかった場合に別のブロックを実行するelse節を含んだ条件実行構文を紹介します[3]。
- else節のあるif文
x = 3 if x == 2 : print("xは2に等しい。") else : print("xは2に等しくありません。") print("プログラムが終了しました。")
- 実行結果
xは2に等しくないよ。 プログラムが終了しました。
なお、elseをつかわないでも、同じ内容の処理が書けます。
- else節を使わず、逆論理の別のif文を使った例
x = 3 if x == 2 : print("xは2に等しい。") if x != 2 : print("xは2に等しくありません。") print("プログラムが終了しました。")
- 2つの例は同じ動作をしますが、後者は「変更漏れの原因となる」という重大な欠点があるので、好んで逆論理のif文を使わずelseを使いましょ。
elif節のあるif文[編集]
else節を使うと、条件式によって2方向にプログラムフローを分けることができました。 実施のプログラムでは、2つ以上の条件式によってプログラムフローを分けることがあります。 そのような場合、次のように条件式ごとにif文が入れ子になります。
- else節のあるif文
x = float("nan") if x < 0 : print("xは0より小さい。") else : if x > 0 : print("xは0より大きい。") else : if x == 0 : print("xは0と等しい。") else : print("xは", x) print("プログラムが終了しました。")
- 実行結果
xはnan プログラムが終了しました。
このプログラムは意味的には正しいのですがインデントが深くなりすぎ、読むのも修正するのも難儀なので、Python にはelse節の中にif文が入れ子になっていことを表すキーワード elif が用意されています。
- elifによる置換え
x = float("nan") if x < 0 : print("xは0より小さい。") elif x > 0 : print("xは0より大きい。") elif x == 0 : print("xは0と等しい。") else : print("xは", x) print("プログラムが終了しました。")
- 実行結果
xはnan プログラムが終了しました。
- インデントが深くなりすぎず読みやすいですね。
if 式[編集]
Python には、if文の他、if式があります。
- コード例
x = 3 print("xは2に等しい。" if x == 2 else "xは2に等しくありません。") print("プログラムが終了しました。")
- 実行結果
xは2に等しくありません。 プログラムが終了しました。
- これで、else の例と同じ意味になります。
- PerlやRubyの後置のifと似ていますが else を伴うので、C言語系の条件演算子と(構文はまるで違いますが)機能的には同じです。
- 大概の場合、if文を使ったほうが読みやすいのですが、内包表記やラムダ式では式が要求されるので、if式を使う必要があります。
nanってナニ? |
唐突に float("nan") 、が出てきましたが、これがPythonでNaN(Not a Number; 非数)を得る方法で、他には math を import して math.nan を使う方法もあります。
nan は、浮動小数点演算の結果として、不正なオペランドを与えられたために生じた結果を表す値またはシンボルで[4]、NaNの体系的仕様は、無限大の表現などと共に1985年の IEEE 754 浮動小数点規格で標準が与えられています。
|
論理演算子[編集]
「変数xは2より大きくて、5より小さい」ときにだけ実行するような処理は、次のように書きます。
x = 3 if x > 2 and x < 5 : print("xは2より大きくて5より小さい。") else: print("そうでない場合。") print("プログラムが終了しました。")
and
は、両方の条件が成り立つという意味です。
上記のコードを実行すると、「
xは2より大きくて5より小さいよ。
」が表示されます。「そうでない場合。」は表示されません。
xを6に変えてみましょう。
x = 6 if x > 2 and x < 5 : print("xは2より大きくて5より小さい。") else: print("そうでない場合。") print("プログラムが終了しました。")
上記のコードを実行すると、「
そうでない場合。
」が表示されます。「xは2より大きくて5より小さいよ。」は表示されません。
演算子 and
をもちいて、
if 条件式A and 条件式B :
のように、使いうことにより、条件式Aと条件式Bが両方とも成り立つ場合に、「条件式A and 条件式B」が成り立つという意味にできます(数理論理学の用語でいう「論理積」です)。
演算子 | 意味 |
---|---|
and |
両方とも真。(「論理積」) |
or |
片方または両方が真。(「論理和」) |
not |
真ならば偽・偽ならば真。(「論理和」) |
複数の比較演算子の連結 |
上記の例では、and 演算子の説明のため
としていますが、これは
と書くこともできます。両者は同じ意味になりますがxの参照は後者は一度だけになります。 |
match文[編集]
Python 3.10 から、パターンマッチングを行う match 文がサポートされました[5]。
正規表現の match メソッドとは別です。
- match文を使った条件分岐
for x in range(10): print(x,"=", end=" ") match x: case 2: print('two') case 5: print('five') case 7: print('seven') case _: print('ELSE')
- 実行結果
0 = ELSE 1 = ELSE 2 = two 3 = ELSE 4 = ELSE 5 = five 6 = ELSE 7 = seven 8 = ELSE 9 = ELSE
- _ は、ワイルドカードバターンで全てにマッチします。
match文は、2021年に導入された新しい機能で、3.9以前のバージョンのpythonではmatch文は使えません。
パターン[編集]
Pythonの match
文で使用されるパターンは、以下のようなものがあります。
value
パターンワイルドカード
パターンガード
パターンtype
パターンas
パターンor
パターンlist
パターンtuple
パターンdict
パターンclass
パターンシーケンス
パターン
以下で、それぞれについて詳しく解説します。
value パターン[編集]
value
パターンは、値が等しいかどうかを比較するためのパターンです。以下は、例です。
match color:
case "red":
print("赤色です")
case "blue":
print("青色です")
case "green":
print("緑色です")
この例では、color
という変数に格納された値に応じて、条件分岐を行っています。case "red":
は、color
が "red"
と等しい場合にマッチします。
ワイルドカード パターン[編集]
ワイルドカードパターンは、どの値にもマッチするパターンです。ワイルドカードパターンは、_
という記号で表現します。
match value:
case _:
# valueがどの値にもマッチする場合の処理
ガード パターン[編集]
ガードパターンは、条件式が True
である場合にマッチするパターンです。ガードパターンは、if
キーワードを使って表現します。
match value:
case x if x > 0:
# valueが0より大きい場合の処理
case y if y < 0:
# valueが0より小さい場合の処理
...
type パターン[編集]
type
パターンは、型が等しいかどうかを比較するためのパターンです。以下は、例です。
match value:
case int:
print("整数型です")
case float:
print("浮動小数点型です")
case str:
print("文字列型です")
case _:
print("不明な型です")
この例では、value
という変数に格納された値の型に応じて、条件分岐を行っています。case int:
は、value
の型が整数型の場合にマッチします。
as パターン[編集]
as
パターンは、値を別名で参照するためのパターンです。以下は、例です。
match value:
case int as n:
print("整数型です。値は", n, "です")
case float as f:
print("浮動小数点型です。値は", f, "です")
case str as s:
print("文字列型です。値は", s, "です")
case _:
print("不明な型です")
この例では、value
という変数に格納された値の型に応じて、条件分岐を行っています。case int as n:
は、value
の型が整数型の場合にマッチし、value
の値を n
という名前で参照することができます。
or パターン[編集]
or
パターンは、二つのパターンのいずれかにマッチする場合に使用されます。例えば、次のように使用します。
match x:
case 0 or 1:
print("x is either 0 or 1")
case 2 or 3:
print("x is either 2 or 3")
case _:
print("x is something else")
list パターン[編集]
list
パターンは、リストに対してマッチする場合に使用されます。次のように、リストの要素を一つ一つマッチングします。
match my_list:
case [0, 1]:
print("my_list is [0, 1]")
case [2, 3]:
print("my_list is [2, 3]")
case [4, _, _]:
print("my_list starts with 4 and has at least 3 elements")
case _:
print("my_list is something else")
tuple パターン[編集]
tuple
パターンは、タプルに対してマッチする場合に使用されます。リストの場合と同様に、タプルの要素を一つ一つマッチングします。
match my_tuple:
case (0, 1):
print("my_tuple is (0, 1)")
case (2, 3):
print("my_tuple is (2, 3)")
case (4, _, _):
print("my_tuple starts with 4 and has at least 3 elements")
case _:
print("my_tuple is something else")
dict パターン[編集]
dict
パターンは、辞書に対してマッチする場合に使用されます。次のように、辞書のキーと値を一つ一つマッチングします。
match my_dict:
case {'a': 1, 'b': 2}:
print("my_dict is {'a': 1, 'b': 2}")
case {'c': 3, 'd': 4}:
print("my_dict is {'c': 3, 'd': 4}")
case {'e': 5, 'f': _}:
print("my_dict has the key 'e' with the value 5 and the key 'f' with some other value")
case _:
print("my_dict is something else")
class パターン[編集]
class
パターンは、特定のクラスのインスタンスに対してマッチする場合に使用されます。次のように、クラス名を指定して、クラスのインスタンスにマッチングします。
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
match my_obj:
case MyClass(0, 1):
print("my_obj is an instance of MyClass with x=0 and y=1")
case MyClass(2, 3):
print("my_obj is an instance of MyClass with x=2
シーケンスパターン[編集]
Pythonのシーケンスパターンは、リスト、タプル、文字列、バイト列のようなシーケンス型のデータをマッチングするために使用されます。シーケンスパターンは、複数の要素を一度にマッチングするために使用され、組み込みの結合演算子を使用して複数のパターンを結合することができます。
以下は、シーケンスパターンを使用してリストをマッチングする例です。
match my_list:
case [1, 2, 3]:
print("Matched [1, 2, 3]")
case [1, _, _]:
print("Matched [1, _, _]")
case [1, *rest]:
print("Matched [1, *rest]")
print("rest =", rest)
case _:
print("Matched anything else")
上記の例では、my_list
が4つの異なるパターンにマッチするように定義されています。最初のパターン [1, 2, 3]
は、my_list
が要素が1, 2, 3のリストである場合にマッチします。2番目のパターン [1, _, _]
は、my_list
が最初の要素が1で、次の2つの要素が何であってもマッチします。3番目のパターン [1, *rest]
は、my_list
が最初の要素が1である場合にマッチし、*rest
はリストの残りの部分をキャプチャします。最後のパターン _
は、どのリストにもマッチするため、最後のパターンは常に True
を返します。
シーケンスパターンは、パターンの部分を任意の式で置き換えることができるため、マッチングされた要素にアクセスして処理を実行することができます。例えば、以下の例ではリストの最初の2つの要素にアクセスしていることがわかります。
match my_list:
case [x, y, *rest]:
print("First two elements:", x, y)
print("Rest of the list:", rest)
この例では、x
とy
は最初の2つの要素を表し、rest
は残りのリストを表します。
rest
はキーワードではありませんが、レストパターンを引き受ける変数の名前としてよく使われます。
連想配列を使った多方向分岐[編集]
上の例は、連想配列を使って下のように書き換えることができます。
- 連想配列を使った例
h = { 2: "two", 5: "five", 7: "seven"} for x in range(10) : print(f"{x} =", x in h and h[x] or "ELSE")
列挙型[編集]
Python 3.4からは、enumモジュールが標準ライブラリとして提供されています[6]。
以下は、enumパッケージを使用した簡単な例です。
from enum import Enum class Color(Enum): RED = 1 GREEN = 2 BLUE = 3
このように、Enum
を継承したクラスを作成し、クラス属性として定数を定義することで、独自の列挙型を定義できます。
上記の例では、Color
という列挙型を定義し、RED
、GREEN
、BLUE
という3つの定数を定義しています。
列挙型を使用すると、例えばColor.RED
というように、定数に直接アクセスすることができます。
print(Color.RED) # Color.RED print(Color.RED.name) # RED print(Color.RED.value) # 1
また、列挙型はfor
ループを使って列挙することができます。
for color in Color: print(color)
match
文と組み合わせると、列挙型の値に基づいた処理を簡潔に記述できます。
match color: case Color.RED: print("Red color") case Color.GREEN: print("Green color") case Color.BLUE: print("Blue color")
Python 3.10以降では、enumパッケージにauto()
という新しい機能が導入されました。これにより、列挙型に自動的に連番の値を割り当てることができます。
from enum import Enum, auto class Color(Enum): RED = auto() GREEN = auto() BLUE = auto() for color in Color: print(color.value)
上記のコードでは、auto()
を使用して列挙型に自動的に連番の値を割り当てています。結果として、Color.RED
は1、Color.GREEN
は2、Color.BLUE
は3の値を持ちます。
- まとめ
# Enumクラスのインポート方法 from enum import Enum # 基本的な列挙型の定義方法 class MyEnum(Enum): VALUE1 = 1 VALUE2 = 2 VALUE3 = 3 # 名前と値の一覧を取得する print(list(MyEnum)) # 特定の名前に対応する値を取得する print(MyEnum.VALUE1.value) # 名前からEnumオブジェクトを取得する print(MyEnum['VALUE2']) # 値からEnumオブジェクトを取得する print(MyEnum(3)) # Enumクラスを比較する class MyEnum(Enum): VALUE1 = 1 VALUE2 = 2 VALUE3 = 3 class MyOtherEnum(Enum): VALUE1 = 1 VALUE2 = 2 VALUE3 = 3 print(MyEnum.VALUE1 == MyOtherEnum.VALUE1) # False print(MyEnum.VALUE1 == MyEnum.VALUE1) # True # Enumクラスを継承して新しい列挙型を定義する class MyExtendedEnum(MyEnum): VALUE4 = 4 VALUE5 = 5 # Enumクラスによる自動値付け from enum import Enum, auto class MyAutoEnum(Enum): VALUE1 = auto() VALUE2 = auto() VALUE3 = auto() print(MyAutoEnum.VALUE1.value) # 1 print(MyAutoEnum.VALUE2.value) # 2 print(MyAutoEnum.VALUE3.value) # 3
繰返し[編集]
繰返しに関するPythonの構文には、while文と for文の2つがあります。
while文[編集]
while 文は、ある条件を満たすあいです、処理を繰返します。
- 構文
while 条件式 : 処理
- コード例
i = "b" while i != "q": i = input("入力した文字を3個、ならべるよ。(終了したい場合はqを入力)") print(3*i)
- 条件式は自動的に論理型に変換されます。
- 上記のプログラムを実行すると、まず「入力した文字を3個、ならべるよ。(終了したい場合はqを入力)」と言われます。
- 入力文字として、たとえば「a」と入力すると、「aaa」と出力表示され、そして再び「入力した文字を3個、ならべるよ。(終了したい場合はqを入力)」と聞かれ、ふたたび入力を待つ状態になります。なので、「b」と入力してみると、「bbb」と出力表示されます。
- 上記のプログラムは、文字「q」が入力されないかぎり、動作がつづく。文字「q」を入力することにより、終了します。
代入演算子[編集]
上記の while 文の例は、代入演算子をつかうと、
- コード例(悪い例)
while (i := input("入力した文字を3個、ならべるよ。(終了したい場合はqを入力)")) != 'q' : print(3*i)
- のように書換えることができます。
while文とif文との組合わせ[編集]
while文はif文と組合わせることもできます。
- while文とif文との組合わせ(悪い例)
while (i := input("文字を入力しましょう。sを入力で物語がスタート。(終了したい場合はqを入力)")) != 'q' : if i == "s": print("はじまりはじまり。") print("むかし、むかし、あるところに、") print("おじいさんとおばあさんが、すんでいました。") print("おしまい")
- 上記のプログラムを実行すると、文字「s」を入力することで「はじまりはじまり。」と表示させることができ、そして「むかし、むかし、あるところに、」「おじいさんとおばあさんが、すんでいました。」「おしまい」と表示します。
- sを入力しなければ、「はじまりはじまり。」などは表示されません。
- このコードは、while の条件式に入力のロジックと終了条件のロジックを合成して読解と修正を困難にしている悪い例です。#break文に改善した例があります。
for文[編集]
- 素朴なfor文
for i in range(5): print("a")
- のように書いて実行すると、組込み関数range()のカッコ内の回数だけ、ブロック内の文を繰り返す。上のコードの場合、実行すると、「a」を5回、表示します。
- 実行結果
a a a a a
forのあとの変数(ループ変数と呼ばれます)は、別にiである必要はなく、特に以後値を参照しない場合は _ を使うと慣習的に「参照しないこと」が明示できます。
- ループ変数が以後参照しないことを明示している例
for _ in range(5): print("a")
ただし、あくまで慣習にすぎず、言語仕様上は _ という名前の変数にすぎないので、_ の値を参照するプログラムを書けば実行でき、インタプリターは何の警告もしません。 また、pylint の様な静的なソースコード診断ツールでは、_ は未使用変数のチェックの対象から外されているなど、言語仕様ではないものの _ を特別な識別子として扱う事は慣例的に定着しているので、_ の値を参照するコードを書かないことを強く推奨します。
慣習上、for文を書くときは、i で回数を数えることが多い[7]。
for i in range(5): print(i)
のように、すると、
- 実行結果
0 1 2 3 4
のように表示されます。 組込み関数 range() は range クラスのオブジェクトを返します。
range以外のオブジェクトとfor文の組み合わせ[編集]
- range以外のオブジェクトとfor文の組み合わせ
li = [2, 3, 5] tu = (10, 20, 30) for i in li: print(i, end=", ") else: print() for i in tu: print(i, end=", ") else: print() for i, j in zip(li, tu): print(i, j, sep=":", end=", ") else: print() print(type(zip(li, tu)))
- 実行結果
2, 3, 5, 10, 20, 30, 2:10, 3:20, 5:30, <class 'zip'>
continue文[編集]
continue文は、ループの先頭に戻ります。continue文を含むループのブロックのcontinue文以降は実行されません。
pass文[編集]
pass文は、なにもしません。 「なにもしないが構文上ブロックが要求される」ケースで使われます。
break文[編集]
while文あるいはfor文のブロックで文「break」を使うと、ループを中断します。
i = "b" while True: i = input("文字を入力しましょう。sを入力で物語がスタート。(終了したい場合はqを入力)) if i == "s": print("はじまりはじまり。") print("むかし、むかし、あるところに、") print("おじいさんとおばあさんが、すんでいました。") print("おしまい") elif i == "q": break
break文で中断する対象は、if文ではありません。break文は、ループを中断するものです。
なおwhile True
のように、while直後の条件式をブール値 True にすると、条件式は常に真となり、永久ループとなります[8]。
ループにつづくelse節[編集]
while文あるいはfor文がbreak文で中断しなかった場合、forにつづくelse節が実行されます。else節は、大概のプログラミング言語ではif文と組合わせて使いますが、Pythonではこれに加え繰返し(while文あるいはfor文)と組合わせることができます。
while+else[編集]
- while+else
i = 0 while i < 100: print(i, end=" ") i += 3 else: print("done!") i = 0 while i < 100: if i > 10: break print(i, end=" ") i += 3 else: print("done!")
- 実行結果
0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 done! 0 3 6 9
- ループを完走した場合は else 節を実行し、break (や return)で中断すると else 節は実行されません。
- 1つ目のwhileループは、変数
i
を0から3ずつ増やし、100以上になるまでループを繰り返します。ループの本体では、変数i
の値を印刷します。end=" "
は、印刷された各値の後に空白を追加し、すべてを1行に表示するためのものです。最後に、else節で"done!"というメッセージを印刷します。 - 2つ目のwhileループは、変数
i
を0から3ずつ増やし、10を超えるまでループを繰り返します。ループの本体では、変数i
の値を印刷し、それが10を超えた場合は、break
ステートメントが呼び出され、ループが終了します。最後に、else節が実行されず、"done!"というメッセージは印刷されません。
ループと結合したelseの使いどころ |
Pythonでは、ループが完走したときに実行されるelse節を置くことができます。
では、このelse節は何に使うのでしょう?
ループ完走のelseを使うと、「因数が見つからなかった」ケースをフラッグなしに表現でき、記述力が向上し、より洗練されたアルゴリズムの探求に貢献しています。 もし、素数集合更新版をフラッグで表現したら、これより遥かに記述性が劣るでしょう。 Python以外の言語では、Zigでも else を伴ったループ構文があります。 |
for+else[編集]
- for+else
h = {2: "two", 5: "five", 7: "seven"} for x in list(h): print(h[x]) else: print("I didn't take a break.") for x, v in h.items(): if x == 7: break print(x, v) else: print("I didn't take a break.")
- 実行結果
two five seven I didn't take a break. 2 two 5 five
- ループをカンストした場合は else 節を実行し、break (や return)で中断すると else 節は実行されません。
ループとelseを組合わせた大域脱出 |
Pythonはgoto分やラベル付きbreak文を持っていないので、大域脱出する場合は
などの工夫が必要です。 ここでは、ループと結合したelseを使った大域脱出を紹介します。
|
ループはスコープを作りません[編集]
Pythonでは、ループはスコープを作りません。
- ループはスコープを作りません
i = "abc" j = "xyz" print(f"forの前: {i=}、{j=}") for i in range(5): j = 2 * i print(f"forの中: {i=}、{j=}") print(f"forの後: {i=}、{j=}")
- 実行結果
forの前: i='abc'、j='xyz' forの中: i=0、j=0 forの中: i=1、j=2 forの中: i=2、j=4 forの中: i=3、j=6 forの中: i=4、j=8 forの後: i=4、j=8
脚註[編集]
- ^ 関数やメソッドの呼出しや復帰 return も制御構造と言えますが、本項では逐次・分岐・繰返しについて述べます。
- ^ “4.1. if Statements” (2021年11月17日). 2021年11月18日閲覧。
- ^ else節は、他の言語と違いfor文とも結合しますので注意してください。
- ^ ただし、Pythonでは math.asin(2) ↑ValueError であったりnanを返す前に例外が上がる事が多々あります。
- ^ “4.6. match Statements” (2021年11月17日). 2021年11月18日閲覧。
- ^ “enum — Support for enumerations” (2021年11月17日). 2021年11月18日閲覧。
- ^ 少なくともFortranではdo文のループ変数に i が常用され、それ以前に数学でも数列の和など i が使用されます。由来は、iteration の i; integer の i など諸説あります。
- ^
while 1:
としても無限ループになりますが、これは整数型が論理型に変換されるとき「0はFalse, 0以外はTrue」に暗黙に変換されることに頼っています(意味を明示するためwhile True:
とすべき)。同様にwhile i:
として、ループ変数 i がゼロになるまで繰り返すのようなコードも暗黙変換に頼っています。このようなコードは小さな変更で最初の意図に反した挙動を示します。たとえば i-=1 を i-=2 にした場合、i=1の次はi=-1となり、ループ終了条件のi=0を経ることなく無限ループになります。この場合はwhile i > 0:
とすべきです。
演算子[編集]
式は、演算子と1項以上のオペランド(被演算子)からなります。 典型的には中置の二項演算子式ですが、単項演算子やif式のような式とは思い難い見た目をしているものもありますが、値を持つ構文要素はすべからく式と考えて構いません。
演算子の優先順位[編集]
次の表は、Pythonにおける演算子の優先順位を、最も高い優先順位(最も拘束力が強い)から最も低い優先順位(最も拘束力が弱い)へとまとめたものです。同じ枠内の演算子は同じ優先順位を持ちます。構文が明示的に与えられていない限り、演算子は二項演算子です。同じボックス内の演算子は左から右へグループ化されます(右から左へグループ化される指数演算を除く)。
比較、メンバーシップテスト、同一性テストはすべて同じ優先順位を持ち、比較のセクションで説明したように、左から右へ連鎖する機能を持っていることに注意してください。
演算子 | 概要 |
---|---|
(expr...) ,[expr...] , {key: value...} , {expr...}
|
結合式または括弧付き式、リスト、辞書、集合 |
x[index] , x[start:stop:step] , x(args...) , x.attr
|
配列要素参照、スライス、関数やメソッドの呼出し、属性参照 |
await x
|
Await 式 |
**
|
指数関数 |
+x , -x , ~x
|
単項プラス、単項マイナス、ビット単位のNOT |
* , @ , / , // , %
|
乗算、行列乗算、除算、剰余有除算、剰余 |
+ , -
|
加算、減算 |
<< , >>
|
シフト演算 |
&
|
ビット単位の AND |
^
|
ビット単位の XOR |
<nowiki>|</nowiki>
|
ビット単位の OR |
in , not in , is , is not , < , <= , > , >= , != , ==
|
メンバーシップテスト、アイデンティティテストなどの比較 |
not x
|
ビット単位の NOT |
and
|
ビット単位の AND |
or
|
ビット単位の OR |
if – else
|
条件演算子 |
lambda
|
ラムダ式 |
:=
|
代入演算子 |
演算子の一覧[編集]
演算 | 構文 | 関数 |
---|---|---|
加算 | a + b
|
add(a, b)
|
連結 | seq1 + seq2
|
concat(seq1, seq2)
|
包含テスト | obj in seq
|
contains(seq, obj)
|
除算 | a / b
|
truediv(a, b)
|
除算 | a // b
|
floordiv(a, b)
|
ビット単位論理積 | a & b
|
and_(a, b)
|
ビット単位排他的論理和 | a ^ b
|
xor(a, b)
|
ビット反転 | ~ a
|
invert(a)
|
ビット単位論理和 | <nowiki>a | b</nowiki>
|
or_(a, b)
|
冪乗 | a ** b
|
pow(a, b)
|
同一性 | a is b
|
is_(a, b)
|
同一性 | a is not b
|
is_not(a, b)
|
インデックス指定代入 | obj[k] = v
|
setitem(obj, k, v)
|
インデックス指定削除 | del obj[k]
|
delitem(obj, k)
|
インデックス指定参照 | obj[k]
|
getitem(obj, k)
|
左シフト | a << b
|
lshift(a, b)
|
剰余 | a % b
|
mod(a, b)
|
乗算 | a * b
|
mul(a, b)
|
行列乗算 | a @ b
|
matmul(a, b)
|
算術否定 | - a
|
neg(a)
|
論理否定 | not a
|
not_(a)
|
単項プラス | + a
|
pos(a)
|
右シフト | a >> b
|
rshift(a, b)
|
スライス指定代入 | seq[i:j] = values
|
setitem(seq, slice(i, j), values)
|
スライス指定削除 | del seq[i:j]
|
delitem(seq, slice(i, j))
|
スライス参照 | seq[i:j]
|
getitem(seq, slice(i, j))
|
文字列フォーマッティング | s % obj
|
mod(s, obj)
|
減算 | a - b
|
sub(a, b)
|
真偽判定 | obj
|
truth(obj)
|
より小 | a < b
|
lt(a, b)
|
より小または一致 | a <= b
|
le(a, b)
|
一致 | a == b
|
eq(a, b)
|
不一致 | a != b
|
ne(a, b)
|
より大または一致 | a >= b
|
ge(a, b)
|
より大 | a > b
|
gt(a, b)
|
初歩的な内容[編集]
関数[編集]
いくつかの処理をまとめたものを、プログラミングでは「関数」(かんすう)といいます。数学でいう「関数」とは、意味がちがうので、気をつけてください。
なお英語では、数学の「関数」のことを function (ファンクション)といいます。プログラミング用語の「関数」のことも英語では function といいます。
もとの英語をみれば、どちらにも「数」にあたる英語(number 「ナンバー」など)が無いことに、注目してください。
プログラミングの「関数」では、かならずしも、数(整数や小数などの「数」)をつかう必要は、ありません。
さて、pythonでは、ユーザーが自分で関数をつくることができます。ユーザーによる関数の作成には「def
」を用います。「def」とは、おそらく定義を意味する英語 definition の頭3文字です。
- コード例
def work() : print("a") print("b") work() work()
- 実行結果
a b a b
このように、繰り返し作業をするときなど、関数が便利です。
関数の定義の書式は、
def 関数名() : 処理内容
というふうになります。
関数名のあとに、コロン記号「:」をつけるのを、忘れないようにしてください。
関数のプロックは、インデントが終わるまでです。
たとえば下記の関数work()の場合、
def work() : print("a") print("b") print("c") work()
関数のブロックは、
print("a") print("b")
までです。
print("c")は、関数work()のブロックの外です。
引数のある関数[編集]
- (コード例)
def func(a) : print("計算するよ") b = a * 2 print(a,"を2倍したら",b) a = 1 func(a) a = 5 func(a) a = 80 func(a)
(実行結果↓)
計算するよ 1 を2倍したら 2 計算するよ 5 を2倍したら 10 計算するよ 80 を2倍したら 160
ある処理を繰返し行いたい場合、関数をつかうことで、記述をへらせます。 関数に作業させる際、関数外で定義された値を、上記のように利用する事ができ、そのような変数を「引数」(ひきすう)といいます。
上記のコードのうち、関数の定義部分は、
def func(a) : print("計算するよ") b = a * 2 print(a,"を2倍したら",b)
↑ この範囲が、関数の定義部分です。
引数のある関数の定義の書式は、
def 関数名(引数) : 処理内容
というふうになります。
「引数」は「ひきすう」と読みます。
引数が2個以上の場合[編集]
def menseki(a,b) : print("面積を計算するよ") print(a * b) a = 3 b = 5 menseki(a,b)
- 結果
面積を計算するよ 15
下記のように、呼び出し時に引数の値を「menseki(3,5)」のように指定することもできます。
def menseki(a,b) : print("面積を計算するよ") print(a * b) menseki(3,5)
- 結果
面積を計算するよ 15
やや難しい内容[編集]
グローバル変数とローカル変数[編集]
""" グローバル変数とローカル変数の例 """ a = 1 b = 2 c = 3 def f2(): """ f2で参照されるa,b,cはグローバル変数 """ print(f"f2:{a=},{b=},{c=},") def func(a) : """ funcで参照されるaは仮引数 funcで参照されるbはローカル変数 funcで参照されるcはグローバル変数 """ b = a * 2 print(f"func:{a=},{b=},{c=},") f2() func(111) print(f"GLOBAL:{a=},{b=},{c=},")
- 実行結果
func:a=111,b=222,c=3, f2:a=1,b=2,c=3, GLOBAL:a=1,b=2,c=3,
- f2
- 関数から呼び出された関数で、仮引数にもローカル変数にも見つからなかった変数は、グローバル変数から探される。
- func
- 仮引数とグローバル変数の名前が同じ場合、仮引数が参照される。
- グローバル変数は仮引数にシャドーイングされる。
- ローカル変数とグローバル変数の名前が同じ場合、ローカル変数が参照される。
- グローバル変数はローカル変数にシャドーイングされる。
- ローカル変数の有効範囲(スコープ)は、関数の終わりまでです。
このようにpythonでは、関数内で数を置きかえる動作は、原則として、関数外の動作に影響を与えません。
組込み関数id[編集]
組込み関数idを使うとオブジェクトのidを得ることができます。 2つの変数同士のidが同じ場合、2つの変数は同じオブジェクトにバインドされています。 大概の型のオブジェクトのidはメモリー上のアドレスですが、整数のようにそうではない型も少数ながらあります。
- idの例
""" idの例 """ a = 1 b = 2 c = 3 def f2(): """ f2で参照されるa,b,cはグローバル変数 """ print(f"f2:{a=}({id(a)=}),{b=}({id(b)=}),{c=}({id(c)=}),") def func(a) : """ funcで参照されるaは仮引数 funcで参照されるbはローカル変数 funcで参照されるcはグローバル変数 """ b = a * 2 print(f"func:{a=}({id(a)=}),{b=}({id(b)=}),{c=}({id(c)=}),") f2() func(111) print(f"GLOBAL:{a=}({id(a)=}),{b=}({id(b)=}),{c=}({id(c)=}),")
- 実行結果
func:a=111(id(a)=9792128),b=222(id(b)=9795680),c=3(id(c)=9788672), f2:a=1(id(a)=9788608),b=2(id(b)=9788640),c=3(id(c)=9788672), GLOBAL:a=1(id(a)=9788608),b=2(id(b)=9788640),c=3(id(c)=9788672),
戻り値[編集]
関数の戻り値(return value;返り値・返却値とも)は、return 文で返します。
- 関数の戻り値
import inspect def f(a) : """ 引数を戻り値とする関数 """ return a print(inspect.getsource(f)) print(f'''\ {f(1)=} {f(3.1415926536)=} {f("string")=} ''') def n(a) : """ return文のない関数 """ pass print(inspect.getsource(n)) print(f'''\ {n(n)=} {n(3.1415926536)=} {n("string")=} ''') def x(a) : """ return文に引数のない関数 """ return print(inspect.getsource(x)) print(f'''\ {x(n)=} {x(3.1415926536)=} {x("string")=} ''')
- 関数は多くのケースで何らかの値を返します。
- これを戻り値とよびます。
- 関数は、return文の引数を戻り値とします。
- return文に出会わず関数定義の終わりに達した場合は、オブジェクトNoneが返ります。
- return文で戻り値を指定しない場合は、オブジェクトNoneが返ります。
- 例
def f(a, b) : return a + b
- この関数は引数 a と b を受けとり、足した結果を返します。
return文による途中終了[編集]
return文があると、その行で関数が終了します。
- 例
def work() : print("a") return 0 print("b") work() work()
- 実行結果
a a
- print("b") が実行されることはありません。
キーワード引数[編集]
関数の仮引数には名前(識別子)がありますが、仮引数を明示して関数の実引数を渡し呼出すことができます。 このような識別子を明示して呼びされた実引数をキーワード引数と言います。
- キーワード引数
def sub(left, right) : return left - right print(f"{sub(3, 4)=}") print(f"{sub(right=8, left=19)=}")
- 実行結果
sub(3, 4)=-1 sub(right=8, left=19)=11
- 同じ関数を、キーワード引数で呼出すことも、従前の引数形式で呼出すこともできます。
- キーワード引数では引数の順序は問わず、仮引数の識別子で参照されます。
- 上記の例では第一引数と第二引数の順序が入れ替わっています。
- #可変長引数関数を使うことで、キーワード引数で呼出されたのか、従前の引数形式で呼出されたかを判別できます。
ディフォルト引数[編集]
関数の引数には、既定値(ディフォルト)を設けることができます。
- 例
def add(a=0, b=0, c=0) : return a+b+c print(f"""\ {add()=} {add(1)=} {add(2,3)=} {add(4,5,6)=} """)
- 実行結果
add()=0 add(1)=1 add(2,3)=5 add(4,5,6)=15
可変長引数関数[編集]
関数の引数は可変長にできます。
- 例
def add(*args, **kwargs) : result = 0 for i in args : result += i for _, i in kwargs.items() : result += i return result print(f"""\ {add()=} {add(1)=} {add(2,3)=} {add(4,5,6)=} {add(1,2,3,4,5,6,7,8,9,10)=} {add(a=1)=} {add(a=2,x=3)=} {add(q=4,p=5,z=6)=} """)
- 実行結果
add()=0 add(1)=1 add(2,3)=5 add(4,5,6)=15 add(1,2,3,4,5,6,7,8,9,10)=55 add(a=1)=1 add(a=2,x=3)=5 add(q=4,p=5,z=6)=15
- この様に、キーワード引数を可変長引数に含めることもできます。
残余引数[編集]
関数の定義で固定された引数とともに、可変長引数を持つことができます。
ここで、残余引数は、可変長引数の後ろに定義される一連の引数です。
残余引数のために、アスタリスク(*
)を使用します。
def my_func(a, b, *args): print(a) print(b) for arg in args: print(arg)
これで、my_func()関数は少なくともaとbの2つの引数を取り、残りの引数を可変長引数として扱います。
多値返却風な処理[編集]
Pythonには、厳密な意味での多値返却はありませんが、タプルやリストを返すことで多値返しに近いことができます。
- 多値返し風な処理
def addsub(x, y) : a, b = x + y, x - y return a, b def mulquoremdiv(x, y) : return x * y, x // y, x % y, x / y a, s = addsub(13, 5) m, q, r, d = mulquoremdiv(19, 7) print(f'''\ {a=}, {s=} {m=}, {q=}, {r=}, {d=} ''')
- 実行結果
a=18, s=8 m=133, q=2, r=5, d=2.7142857142857144
「多値返却風な処理」や「多値返しに近いこと」と歯切れが悪いのは、型アノテーションを
def addsub(x: int, y: int) -> int, int: # Error! a, b = x + y, x - y return a, b def mulquoremdiv(x: int, y: int) -> int, int, int, float: # Error! return x * y, x // y, x % y, x / y
としたいのですが、
from typing import Tuple def addsub(x: int, y: int) -> Tuple[int, int]: a, b = x + y, x - y return a, b def mulquoremdiv(x: int, y: int) -> Tuple[int, int, int, float] : return x * y, x // y, x % y, x / y
としなければならず、タプルを返していることを明確に意識する必要があるからです。
デコレーター[編集]
デコレーター(decorator)は、関数の内容を書き換えずに修飾するための仕組みです。 関数の引数に関数を指定します。既存の関数の前に@{デコレーター名}を付けることで、その関数を修飾することができます。
- 形式
def デコレーター名(デコレーターの引数) : def ラッパー関数名(*args, **kwargs) : # 前処理 result = デコレーターの引数(*args, **kwargs) # 後処理 return result return ラッパー関数名 @デコレーター名 def 修飾される側の関数(その引数) : 修飾される側の関数の処理
- コード例
def my_decorator(fn) : def _wrapper(*args, **kwargs) : print(f"my_decorator<prologue>:{fn.__name__=}:{args=}, {kwargs=}") result = fn(*args, **kwargs) print(f"my_decorator<epilogue>:{result=}") return result return _wrapper @my_decorator def calc(left, right) : return left + right print(f'''\ {calc(3, 5)=} {calc(right=8, left=9)=}''')
- 実行結果
my_decorator<prologue>:fn.__name__='calc':args=(3, 5), kwargs={} my_decorator<epilogue>:result=8 my_decorator<prologue>:fn.__name__='calc':args=(), kwargs={'right': 8, 'left': 9} my_decorator<epilogue>:result=17 calc(3, 5)=8 calc(right=8, left=9)=17
デコレターの文法は、以下のような糖衣構文です。
@my_decorator def fn(...): ... # は def fn(...): ... fn = my_decorator(fn) #と同じ
デコレーター・パターン |
デコレーター・パターンは、オブジェクト指向プログラミングにおいて、同じクラスの他のオブジェクトの動作に影響を与えることなく、個々のオブジェクトに動的に動作を追加することができるデザインパターンです。 デコレーター・パターンは、単一責任原則(Single Responsibility Principle)を遵守するために有用で、独自の関心領域を持つクラス間で機能を分割することができます。 デコレーターの使用は、全く新しいオブジェクトを定義することなく、オブジェクトの動作を拡張することができるため、サブクラス化よりも効率的です。 Pythonのデコレーター構文は、デコレーター・パターンの言語支援と言えます。 |
global 文[編集]
ローカル変数や仮引数にグローバル変数がシャドーイングされた場合、 関数の中でも、
global 変数
と変数宣言することにより、その変数をグローバル変数として取り扱えます。
- コード例
a = 10 b = 11 def func(a) : global b print(f"func:{a=},{b=}") b = a * 2 print(f"func:{a=},{b=}") func(a) print(f"GLOBAL:{a=},{b=}")
- 表示結果
func:a=10,b=11 func:a=10,b=20 GLOBAL:a=10,b=20
C言語には、このような機能(関数内で変数をグローバル宣言する機能)は、ありません。 C++では、グローバル変数の参照に :: を前置することでシャドーイングを回避できます。
関数内で新たなグローバル変数を作る[編集]
- コード例
a = 10 def func(a) : global b # print(f"func:{a=},{b=}") ← この時点では b は未定義 b = a * 2 print(f"func:{a=},{b=}") func(a) print(f"GLOBAL:{a=},{b=}")
- 表示結果
func:a=10,b=20 GLOBAL:a=10,b=20
nonlocal文[編集]
nonlocal文は、内包関数から、自分を呼び出した関数のローカル変数にアクセスする仕組みです。 global文と違い、新たな変数を作ることはできません。
- コード例
def outer() : f = 25 def inner() : # 関数内関数 nonlocal f f = 13 return 1 inner() print(f) outer()
- 実行結果
13
- nonlocal の行をコメントにすると、結果は 「25」 に変わります。
クロージャ[編集]
クロージャ(関数クロージャ)は、外側の変数を格納する関数です。
- コード例
def f(z) : def _f() : nonlocal z z += 1 return z return _f q = f(-2) print(q()) print(q()) print(q()) print(q())
- 実行結果
-1 0 1 2
- _fをクロージャ、fをエンクロージャといいます。
この絵柄に見覚えがある人もいると思います。デコレーターの引数(デコレート対象の関数)はラッパー関数は格納した変数です。
シーケンス[編集]
Pythonでは、複数のオブジェクトを要素として持つオブジェクト(=コレクション)のうち、整数のインデックスによって要素を参照できるオブジェクトのグループをシーケンス(sequence)と呼びます[1]。 組込み型の代表的なシーケンスは、リスト、タプル、レンジ オブジェクトです[2]。
スライス記法[編集]
シーケンスに共通の機能として、スライス記法があります。
- スライス記法
for li in ( [i for i in range(10)], (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), range(10), "0123456789", b"0123456789", ): print( f"""\ {type(li)=} {li=} {li[2:]=} {li[2:6]=} {li[:6]=} {li[:]=} {id(li)=},{id(li[:])=} {id(li)=},{id(li[:9])=} {li[1:8:2]=} {li[1::2]=} """ )
- 実行結果
type(li)=<class 'list'> li=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] li[2:]=[2, 3, 4, 5, 6, 7, 8, 9] li[2:6]=[2, 3, 4, 5] li[:6]=[0, 1, 2, 3, 4, 5] li[:]=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] id(li)=23247490610496,id(li[:])=23247489732224 id(li)=23247490610496,id(li[:9])=23247489732224 li[1:8:2]=[1, 3, 5, 7] li[1::2]=[1, 3, 5, 7, 9] type(li)=<class 'tuple'> li=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) li[2:]=(2, 3, 4, 5, 6, 7, 8, 9) li[2:6]=(2, 3, 4, 5) li[:6]=(0, 1, 2, 3, 4, 5) li[:]=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) id(li)=23247491653056,id(li[:])=23247491653056 id(li)=23247491653056,id(li[:9])=23247490368448 li[1:8:2]=(1, 3, 5, 7) li[1::2]=(1, 3, 5, 7, 9) type(li)=<class 'range'> li=range(0, 10) li[2:]=range(2, 10) li[2:6]=range(2, 6) li[:6]=range(0, 6) li[:]=range(0, 10) id(li)=23247491019616,id(li[:])=23247490390464 id(li)=23247491019616,id(li[:9])=23247490390464 li[1:8:2]=range(1, 8, 2) li[1::2]=range(1, 10, 2) type(li)=<class 'str'> li='0123456789' li[2:]='23456789' li[2:6]='2345' li[:6]='012345' li[:]='0123456789' id(li)=23247489812400,id(li[:])=23247489812400 id(li)=23247489812400,id(li[:9])=23247489814704 li[1:8:2]='1357' li[1::2]='13579' type(li)=<class 'bytes'> li=b'0123456789' li[2:]=b'23456789' li[2:6]=b'2345' li[:6]=b'012345' li[:]=b'0123456789' id(li)=23247491020288,id(li[:])=23247491020288 id(li)=23247491020288,id(li[:9])=23247490390224 li[1:8:2]=b'1357' li[1::2]=b'13579'
シーケンス・オブジェクトごとのアトリビュートの有無[編集]
組込み関数hasattr(obj, name)を使うと、オブジェクトobjが名前nameな属性を持っているかの検査ができます。
- シーケンス・オブジェクトごとのアトリビュートの有無
sequences = ( [i for i in range(10)], (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), range(10), "0123456789", b"0123456789", zip([],[]), ) attrs = set() for li in sequences: for x in dir(li): attrs.add(x) c = 0 for x in sorted(attrs): if c % 10 == 0: print("Type", ", ".join(str(type(li)) for li in sequences), sep=": ") print(x, ", ".join("o" if hasattr(li, x) else "x" for li in sequences), sep=": ") c += 1 else: print("Type", ", ".join(str(type(li)) for li in sequences), sep=": ")
- 実行結果
Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> __add__: o, o, x, o, o, x __bool__: x, x, o, x, x, x __class__: o, o, o, o, o, o __contains__: o, o, o, o, o, x __delattr__: o, o, o, o, o, o __delitem__: o, x, x, x, x, x __dir__: o, o, o, o, o, o __doc__: o, o, o, o, o, o __eq__: o, o, o, o, o, o __format__: o, o, o, o, o, o Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> __ge__: o, o, o, o, o, o __getattribute__: o, o, o, o, o, o __getitem__: o, o, o, o, o, x __getnewargs__: x, o, x, o, o, x __gt__: o, o, o, o, o, o __hash__: o, o, o, o, o, o __iadd__: o, x, x, x, x, x __imul__: o, x, x, x, x, x __init__: o, o, o, o, o, o __init_subclass__: o, o, o, o, o, o Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> __iter__: o, o, o, o, o, o __le__: o, o, o, o, o, o __len__: o, o, o, o, o, x __lt__: o, o, o, o, o, o __mod__: x, x, x, o, o, x __mul__: o, o, x, o, o, x __ne__: o, o, o, o, o, o __new__: o, o, o, o, o, o __next__: x, x, x, x, x, o __reduce__: o, o, o, o, o, o Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> __reduce_ex__: o, o, o, o, o, o __repr__: o, o, o, o, o, o __reversed__: o, x, o, x, x, x __rmod__: x, x, x, o, o, x __rmul__: o, o, x, o, o, x __setattr__: o, o, o, o, o, o __setitem__: o, x, x, x, x, x __sizeof__: o, o, o, o, o, o __str__: o, o, o, o, o, o __subclasshook__: o, o, o, o, o, o Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> append: o, x, x, x, x, x capitalize: x, x, x, o, o, x casefold: x, x, x, o, x, x center: x, x, x, o, o, x clear: o, x, x, x, x, x copy: o, x, x, x, x, x count: o, o, o, o, o, x decode: x, x, x, x, o, x encode: x, x, x, o, x, x endswith: x, x, x, o, o, x Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> expandtabs: x, x, x, o, o, x extend: o, x, x, x, x, x find: x, x, x, o, o, x format: x, x, x, o, x, x format_map: x, x, x, o, x, x fromhex: x, x, x, x, o, x hex: x, x, x, x, o, x index: o, o, o, o, o, x insert: o, x, x, x, x, x isalnum: x, x, x, o, o, x Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> isalpha: x, x, x, o, o, x isascii: x, x, x, o, o, x isdecimal: x, x, x, o, x, x isdigit: x, x, x, o, o, x isidentifier: x, x, x, o, x, x islower: x, x, x, o, o, x isnumeric: x, x, x, o, x, x isprintable: x, x, x, o, x, x isspace: x, x, x, o, o, x istitle: x, x, x, o, o, x Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> isupper: x, x, x, o, o, x join: x, x, x, o, o, x ljust: x, x, x, o, o, x lower: x, x, x, o, o, x lstrip: x, x, x, o, o, x maketrans: x, x, x, o, o, x partition: x, x, x, o, o, x pop: o, x, x, x, x, x remove: o, x, x, x, x, x replace: x, x, x, o, o, x Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> reverse: o, x, x, x, x, x rfind: x, x, x, o, o, x rindex: x, x, x, o, o, x rjust: x, x, x, o, o, x rpartition: x, x, x, o, o, x rsplit: x, x, x, o, o, x rstrip: x, x, x, o, o, x sort: o, x, x, x, x, x split: x, x, x, o, o, x splitlines: x, x, x, o, o, x Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'> start: x, x, o, x, x, x startswith: x, x, x, o, o, x step: x, x, o, x, x, x stop: x, x, o, x, x, x strip: x, x, x, o, o, x swapcase: x, x, x, o, o, x title: x, x, x, o, o, x translate: x, x, x, o, o, x upper: x, x, x, o, o, x zfill: x, x, x, o, o, x Type: <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'str'>, <class 'bytes'>, <class 'zip'>
脚註[編集]
リストと文字列[編集]
リストの要素は、文字列だけ、あるいは数値だけでも、かまいません。
文字列だけのリストの場合、たとえば
- コード例
myList = ["aaa" ,"bb" ,"cccc"] myList[0] = 4 print(myList)
- 実行結果
[4, 'bb', 'cccc']
また、リストは数値と文字が下記のように混在することも、別々の項なら可能です。
- コード例
myList = [12 ,"bb" , 84] print(myList[0] +5)
- 実行結果
17
他のプログラミング言語だと、数値と文字列とが混在するデータ構造をつくるのにクラスを使わないといけない言語もありますが、しかしPythonではクラスを使わずとも、リストだけで数値との共存が可能です。
for文との組み合わせ[編集]
リストは、for文の対象となるコレクションとして使えます。
- コード例
names = ["yamada" ,"sato" ,"inoue"] # 人名リスト for i in names : print(i)
- 実行結果
yamada sato inoue
要素の追加[編集]
リストの要素に、あとから追加することもできます。
myList = ["aaa" ,"bb" ,"cccc"] myList.append("d") print(myList)
- 実行結果
['aaa', 'bb', 'cccc', 'd']
python のリストを希望の数だけ予め確保するには、myList = [0] * 100
の様に、初期値を持った配列に乗算演算子を作用し、所望の個数を指定した式の値を与えます。
勿論、律儀に要素を1つづつ追加する方法も有効です。
myList = [] myList.append(123) myList.append(5) print(myList)
- 実行結果
[123, 5]
要素の削除[編集]
リストの要素を、あとから削除することもできます。次のコードのようにpop()
を使うと、リスト末尾の要素を削除できます。
myList = ["aaa" ,"bb" ,"cccc"] myList.pop() print(myList)
- 実行結果
['aaa', 'bb']
要素の末尾を削除したいリストのうしろに「.pop()」をつけ、ることで、要素の末尾を削除していけます。
なお、この.pop()のような、操作したい対象物のうしろにドット記号(.)と操作内容のキーワードをつける特別な関数のことをpythonでは、「メソッド」といいます。
myList.pop()をくりかえすと、さらに末尾から、削除していきます。
myList = ["aaa" ,"bb" ,"cccc"] myList.pop() myList.pop() print(myList)
- 実行結果
['aaa']
リストの要約[編集]
リスト( list )は、任意のオブジェクトをゼロ個以上、順次付けて保持できるコレクションです[1]。
リストリテラル[編集]
- リストリテラル
print(f"""\ {[]=} {list()=} {list((1,2,3))=} {list(i for i in range(5))=} {[10,"ABC"]=} {[[1,"one"], [2,"two"],[3,"three"]]=} {[ [1,"壱"], [2,"弐"], [3,"参"] ]=} """)
- 実行結果
[]=[] list()=[] list((1,2,3))=[1, 2, 3] list(i for i in range(5))=[0, 1, 2, 3, 4] [10,"ABC"]=[10, 'ABC'] [[1,"one"], [2,"two"],[3,"three"]]=[[1, 'one'], [2, 'two'], [3, 'three']] [ [1,"壱"], [2,"弐"], [3,"参"] ]=[[1, '壱'], [2, '弐'], [3, '参']]
リストは、要素を ,(カンマ) で区切り全体を [ ] で囲みます。 要素の型は同じである必要はありません。
リストと演算子[編集]
- リストと演算子
li = [10 ,"ABC" ,30] print(f'''\ {li=} {li[1]=} {li[-1]=} {li + [2,3,4]=} {li * 2=} {2 * li=} {li == [10 ,"ABC" ,30]=} {li != [10 ,"ABC" ,30]=} {li < [10 ,"ABC" ,30]=} {li > [10 ,"ABC" ,30]=} ''')
- 実行結果
li=[10, 'ABC', 30] li[1]='ABC' li[-1]=30 li + [2,3,4]=[10, 'ABC', 30, 2, 3, 4] li * 2=[10, 'ABC', 30, 10, 'ABC', 30] 2 * li=[10, 'ABC', 30, 10, 'ABC', 30] li == [10 ,"ABC" ,30]=True li != [10 ,"ABC" ,30]=False li < [10 ,"ABC" ,30]=False li > [10 ,"ABC" ,30]=False
- リストの要素は、インデックス演算子で参照できます。
- リスト内の要素の順位はタプルやレンジと同じく、0番から始まります。
- 負のインデクスiは、
len(self)+i
を表します。 - リスト同士の足し算は、連結した新しいリストを返します。
- リストtと整数nとの乗算は、tをn回繰り返したリストを返します。
- 整数nとリストtとの乗算は、tをn回繰り返したリストを返します。
- リスト同士は、比較や大小判別ができます。
リストはミュータブル[編集]
リストの各要素を、代入・置き換えすることもできます。
myList = [10 ,"ABC" ,30] myList[0] = 4 print (myList)
- 実行結果
[4, 'ABC', 30]
- です。「10」が「4」に置き換わっています。
多次元リスト[編集]
リストの中にリストを入れることも出来ます。ただし、下記のように入れたリストの項目数が等しくなるようにする必要があります。
リストの中にリストを入れたものを2次元リスト(または2重リスト)といい、
リストの中にリストを入れたもののなかに、さらにリストを入れたものを3次元リストと言います。
- 二次元リストのコード例
carList = [ ["山田" , "red" , 1234 ] , ["伊藤" , "blue" , 555 ] ] print(carList[0][0] ) print(carList[0][1] ) print(carList[1][0] )
- 実行結果
山田 red 伊藤
map関数[編集]
組込み関数mapを使うと、iterableオブジェクトの全ての要素に、一括で何かの関数を適用する事ができます。
- 関数宣言
map(function, iterable)
- コード例
myList = [-7 , -2, 5] print(f'''\ {myList=} {map(abs, myList)=} {list(map(abs, myList))=} {list(abs(x) for x in myList)=} {[abs(x) for x in myList]=} {[-x if x < 0 else x for x in myList]=} ''')
- 実行結果
myList=[-7, -2, 5] map(abs, myList)=<map object at 0x149ab6e4c0d0> list(map(abs, myList))=[7, 2, 5] list(abs(x) for x in myList)=[7, 2, 5] [abs(x) for x in myList]=[7, 2, 5] [-x if x < 0 else x for x in myList]=[7, 2, 5]
- リスト myList の要素の絶対値を得るプログラムです。
- map関数の第一引数は関数が要求されますが、1つの引数を取り値を帰っす必要があります。ここでは組込み関数absを使いました。
- map関数はリスト...ではなく map object を返します。
- map objectはリストコンストラクタであるlist関数でリスト化できます。
- map関数はジェネレーター式
(function(x) for x in iterable)
と等価です。 - またリスト化するなら、リスト内包表記
[function(x) for x in iterable]
と等価です。 - 内包表記であれば、absの呼出しは条件演算子
-x if x < 0 else x
で置換える事ができます。
abs のような組込み関数だけでなく、ユーザー定義関数やlambdaもmap関数の第一引数にすることができます。
filter関数[編集]
組込み関数filterは、iterableオブジェクトの要素の中から、条件に適合するものだけを選び出して、新たなリストを作ります、
- 関数宣言
filter(function, iterable)
- 引数
-
- function
- 残すかの条件関数False以外を返すと残す
- iterable
- 対処とするiterableオブジェクト
- コード例
myList = [5, 2, 8, 3, 6, 1] print(f'''\ {myList=} {filter(lambda x:x >= 3, myList)=} {list(filter(lambda x:x >= 3, myList))=} {list(x for x in myList if x >= 3)=} {[x for x in myList if x >= 3]=} ''')
- 実行結果
myList=[5, 2, 8, 3, 6, 1] filter(lambda x:x >= 3, myList)=<filter object at 0x154a32dccd00> list(filter(lambda x:x >= 3, myList))=[5, 8, 3, 6] list(x for x in myList if x >= 3)=[5, 8, 3, 6] [x for x in myList if x >= 3]=[5, 8, 3, 6]
- リスト myList から3より多い要素を残すプログラムです。
- filter関数の第一引数は関数を要求されますが、名前は不要で繰返し使う予定もないので lambda を使いました。
- filter関数はリスト...ではなく filter object を返します。
- filter objectはリストコンストラクタであるlist関数でリスト化できます。
- filter関数はジェネレーター式
(x for x in iterable if function(x))
と等価です。 - またリスト化するなら、リスト内包表記
[x for x in iterable if function(x)]
と等価です。
filter関数の第一引数をNoneとした場合[編集]
- コード例
myList = [5, set(), 8, "", 3, False, 6, None, 1, tuple(), 0, 3, []] print(f'''\ {myList=} {filter(None, myList)=} {list(filter(None, myList))=} {list(x for x in myList if x)=} {[x for x in myList if x]=} ''')
- 実行結果
myList=[5, set(), 8, '', 3, False, 6, None, 1, (), 3, []] filter(None, myList)=<filter object at 0x1514a15ee0d0> list(filter(None, myList))=[5, 8, 3, 6, 1, 3] list(x for x in myList if x)=[5, 8, 3, 6, 1, 3] [x for x in myList if x]=[5, 8, 3, 6, 1, 3]
- リスト myList からfalsy[2]でない要素を残すプログラムです。
- filter関数の第一引数は関数を要求されますが、Noneを渡すとfalsyな要素を除去します。
- この場合も、filter関数はリスト...ではなく filter object を返します。
- この場合も、filter objectはリストコンストラクタであるlist関数でリスト化できます。
- この場合は、filter関数はジェネレーター式
(x for x in iterable if x)
と等価です。 - この場合はリスト化するなら、リスト内包表記
[x for x in iterable if x]
と等価です。
リスト内包表記を使った例[編集]
上記のmap関数とfilter関数の使用例はリスト内包表記をつかうと
- コード例
myList = [-7 , -2, 5] obj = [abs(i) for i in myList] print(obj) myList = [5, 2, 8, 6, 1] obj = [i for i in myList if i >= 3] print(obj)
と表現できます。 for式やif式、if-else式(条件演算子)はリスト内包表記と組合わせると関数呼出しを使わないでもイテレーションやケース分けができます。
絶対値を求める部分も、
obj = [-i if i < 0 else i for i in myList]
とインラインで表現できます。
リストのフィールド一覧[編集]
- リストのフィールド一覧
obj = [] for i in dir(obj): print(i, eval(f"type({obj}.{i})"))
- 実行結果
__add__ <class 'method-wrapper'> __class__ <class 'type'> __contains__ <class 'method-wrapper'> __delattr__ <class 'method-wrapper'> __delitem__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'builtin_function_or_method'> __gt__ <class 'method-wrapper'> __hash__ <class 'NoneType'> __iadd__ <class 'method-wrapper'> __imul__ <class 'method-wrapper'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __mul__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __reversed__ <class 'builtin_function_or_method'> __rmul__ <class 'method-wrapper'> __setattr__ <class 'method-wrapper'> __setitem__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> append <class 'builtin_function_or_method'> clear <class 'builtin_function_or_method'> copy <class 'builtin_function_or_method'> count <class 'builtin_function_or_method'> extend <class 'builtin_function_or_method'> index <class 'builtin_function_or_method'> insert <class 'builtin_function_or_method'> pop <class 'builtin_function_or_method'> remove <class 'builtin_function_or_method'> reverse <class 'builtin_function_or_method'> sort <class 'builtin_function_or_method'>
リストと演算子[編集]
- リストと演算子
print(f'''\ {[1,2,3] + [7,8,9] =} {[1,2,3] * 2 =} {2 in [1,2,3] =} {[1,2,3] == [7,8,9] =} {[1,2,3] == [1,2,3] =} {[1,2,3] != [7,8,9] =} {[1,2,3] != [1,2,3] =} {[1,2,3] > [1,2] =} {[1,2,3] < [1,2] =} ''') import operator print(f'''\ {operator.__add__([1,2,3], [7,8,9]) =} {operator.__mul__([1,2,3], 2) =} {operator.__contains__([1,2,3],2)=} {operator.__eq__([1,2,3], [7,8,9]) =} {operator.__eq__([1,2,3], [1,2,3]) =} {operator.__ne__([1,2,3], [7,8,9]) =} {operator.__ne__([1,2,3], [1,2,3]) =} {operator.__gt__([1,2,3], [1,2]) =} {operator.__lt__([1,2,3], [1,2]) =} ''') print(", ".join(vars(operator)))
- 実行結果
[1,2,3] + [7,8,9] =[1, 2, 3, 7, 8, 9] [1,2,3] * 2 =[1, 2, 3, 1, 2, 3] 2 in [1,2,3] =True [1,2,3] == [7,8,9] =False [1,2,3] == [1,2,3] =True [1,2,3] != [7,8,9] =True [1,2,3] != [1,2,3] =False [1,2,3] > [1,2] =True [1,2,3] < [1,2] =False operator.__add__([1,2,3], [7,8,9]) =[1, 2, 3, 7, 8, 9] operator.__mul__([1,2,3], 2) =[1, 2, 3, 1, 2, 3] operator.__contains__([1,2,3],2)=True operator.__eq__([1,2,3], [7,8,9]) =False operator.__eq__([1,2,3], [1,2,3]) =True operator.__ne__([1,2,3], [7,8,9]) =True operator.__ne__([1,2,3], [1,2,3]) =False operator.__gt__([1,2,3], [1,2]) =True operator.__lt__([1,2,3], [1,2]) =False __name__, __doc__, __package__, __loader__, __spec__, __file__, __cached__, __builtins__, __all__, _abs, lt, le, eq, ne, ge, gt, not_, truth, is_, is_not, abs, add, and_, floordiv, index, inv, invert, lshift, mod, mul, matmul, neg, or_, pos, pow, rshift, sub, truediv, xor, concat, contains, countOf, delitem, getitem, indexOf, setitem, length_hint, attrgetter, itemgetter, methodcaller, iadd, iand, iconcat, ifloordiv, ilshift, imod, imul, imatmul, ior, ipow, irshift, isub, itruediv, ixor, __lt__, __le__, __eq__, __ne__, __ge__, __gt__, __not__, __abs__, __add__, __and__, __floordiv__, __index__, __inv__, __invert__, __lshift__, __mod__, __mul__, __matmul__, __neg__, __or__, __pos__, __pow__, __rshift__, __sub__, __truediv__, __xor__, __concat__, __contains__, __delitem__, __getitem__, __setitem__, __iadd__, __iand__, __iconcat__, __ifloordiv__, __ilshift__, __imod__, __imul__, __imatmul__, __ior__, __ipow__, __irshift__, __isub__, __itruediv__, __ixor__
- モジュールoperatorを使うと、演算子を関数形式で呼び出すことができます[3]。
他のプログラミング言語との比較[編集]
他のプログラミング言語とPythonの類似点と差異をリストを中心に比較します。
- Python
compound = [ 10, 20, 30 ]
- Ruby
compound = [ 10, 20, 30 ]
- 完全に一致
- JavaScript
let compound = [ 10, 20, 30 ]
- let があること以外同じ
- JavaScript(TypedArray)
let compound = new Int32Array([10,20,30])
- ECMAScript 2015(ES6)でTypedArray(型付き配列)が追加されました。
- TypedArrayはJSの配列とは違い、単一要素型で連続したメモリーに割当てられます。
- C言語
int compound[] = { 10, 20, 30 };
- だいぶ違う
- 意味的にも、C言語の配列は全ての要素の型は同一で連続したメモリーに割り付けられます。
- Go(配列)
compound := [...]int{ 10, 20, 30 }
- C言語ともだいぶ違う
- 意味的には、C言語の配列と同じく全ての要素の型は同一で連続したメモリーに割り付けられます。
- Go(スライス)
compound := []int{ 10, 20, 30 }
- よく似た構文ですが [ ] の中に ... がないのはスライス
- スライスの要素は離散的なアドレスに配置され、動的に長さ(要素数)の変更が可能です。
宣言と初期化の部分に注目し様々な差異がありましたが、要素の参照は、
- Python
compound[1]
の構文で、この部分はどの言語でもほぼ同じですが、FortranとBASICでは、
- Fortran, BASIC
compound(1)
のように丸括弧になります。
- それぞれの言語のリストに似た型
Pythonに「配列」というデータ型は存在しません[4]。C言語などに、配列というデータ型があります。
言語によっては、「配列」データ型と「リスト」データ型とが別個に存在するものもあります(たとえば Kotlin という言語には、配列(array)データ型と、リスト list データ型とが別々に存在します) なお、kotlin は現在では、Android スマートホンのアプリケーションプログラムの開発などで、よく使われる言語です。
また、Goには「リスト」はなく「スライス」slice があります(Goのスライスの機能はPythonやkotlinの「リスト」と一見似ていますが、Goのスライスは「要素の型が一致している必要がある」ので本質的に「リスト」とは違い、異種リストの実装には interface{} を使います)。
Goには、配列型と「スライス」slice の2つのデータ型がありよく混同されますが、スライスは要素のアクセスは線形時間 O(n)、配列の要素のアクセスは定数時間 O(1)であることが大きな違いです。
要素の参照速度による分類[編集]
リストや配列に類似した型は、要素の参照にかかる時間によって
- 線形時間 O(n)が必要なもの
- Pythonのリスト、Goのスライスはこれに当たります
- 個々の要素の型は異なっても良い
- 要素数の増減可能
- 定数時間 O(1)で済むもの
- Pythonの標準モジュールの array や拡張モジュール NumPy、JavaScriptのTypedArray、C言語の配列、Goの配列
- 個々の要素の型は一致している必要がある
- 要素数は宣言時に確定する
- 宣言時の要素数に定数式しか受け付けない言語(過去のC言語やGo)と、宣言時の要素数に実行時まで確定しない式も受け付ける言語(現在のC言語など)がある
タプル[編集]
タプル( tuple )は、任意のオブジェクトをゼロ個以上、順次付けて保持できるコレクションです[5]。 リストとよく似た特徴がありますが、リストと違い生成後は内容が変更できない「イミュータブル」なオブジェクトです。
タプルリテラル[編集]
- タプルリテラル
tpl0 = () tpl1 = (10,) tpl2 = 10, "ABC", 30 tpl3 = (1,"one"), (2,"two"),(3,"three") tpl4 = ( (1,"壱"), (2,"弐"), (3,"参") ) print(tpl0) print(tpl1) print(tpl2) print(tpl3) print(tpl4)
- 実行結果
() (10,) (10, 'ABC', 30) ((1, 'one'), (2, 'two'), (3, 'three')) ((1, '壱'), (2, '弐'), (3, '参'))
- 空のタプルは、空の括弧の組で作ることができます。
- 1つの項目からなるタプル(「シングルトン」(singleton))は、式にカンマを付けることで形成されます(式はそれ自体ではタプルを作らないので、括弧 ( ) は式のグループ化のために使用可能でなければならないからです)。
- 2つ以上の項目からなるタプルリテラルは、カンマで区切られた式のリストで形成されます。
- タプルリテラルに限らず、式を括弧 ( ) で括ると複数行に渡って書くことができます。
タプルと演算子[編集]
- タプルと演算子
tpl = 10 ,"ABC" ,30 print(f'''\ {tpl=} {tpl[1]=} {tpl[-1]=} {tpl + (2,3,4)=} {tpl * 2=} {2 * tpl=} {tpl == (10 ,"ABC" ,30)=} {tpl != (10 ,"ABC" ,30)=} {tpl < (10 ,"ABC" ,30)=} {tpl > (10 ,"ABC" ,30)=} ''')
- 実行結果
tpl=(10, 'ABC', 30) tpl[1]='ABC' tpl[-1]=30 tpl + (2,3,4)=(10, 'ABC', 30, 2, 3, 4) tpl * 2=(10, 'ABC', 30, 10, 'ABC', 30) 2 * tpl=(10, 'ABC', 30, 10, 'ABC', 30) tpl == (10 ,"ABC" ,30)=True tpl != (10 ,"ABC" ,30)=False tpl < (10 ,"ABC" ,30)=False tpl > (10 ,"ABC" ,30)=False
- タプルの要素は、インデックス演算子で参照できますが、左辺値は得られません(イミュータブルなので)。
- タプル内の要素の順位はリストと同じく、0番から始まります。
- 負のインデクスiは、
len(self)+i
を表します。 - タプル同士の足し算は、連結した新しいタプルを返します。
- タプルtと整数nとの乗算は、tをn回繰り返したタプルを返します。
- 整数nとタプルtとの乗算は、tをn回繰り返したタプルを返します。
- タプル同士は、比較や大小判別ができます。
タプルのフィールド一覧[編集]
- タプルのフィールド一覧
obj = tuple() for i in dir(obj): print(i, eval(f"type({obj}.{i})"))
- 実行結果
__add__ <class 'method-wrapper'> __class__ <class 'type'> __contains__ <class 'method-wrapper'> __delattr__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'method-wrapper'> __getnewargs__ <class 'builtin_function_or_method'> __gt__ <class 'method-wrapper'> __hash__ <class 'method-wrapper'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __mul__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __rmul__ <class 'method-wrapper'> __setattr__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> count <class 'builtin_function_or_method'> index <class 'builtin_function_or_method'>
メソッドセットはリストに準じますが、イミュータブルなので append clear copy extend insert pop remove reverse sort の9つのメソッドはありません。
脚註[編集]
- ^ “3.10.1 Documentation » The Python Language Reference » 3. Data model ¶3.2. The standard type hierarchy” (2021年12月16日). 2021年12月16日閲覧。
- ^ falsy: 組込み関数bool() に与えると False を返すような式。False, None の他、空集合(set())、空文字列()、0、空タプル(tuple())、空リスト([])など
- ^ “operator — Standard operators as functions — Python 3.10.1 documentation” (2021年12月15日). 2021年12月15日閲覧。
- ^ 標準モジュールの array あるいは、拡張モジュールの NumPy で連続した領域に要素が配置される配列が提供されますが、組込みオブジェクトの配列はありません。
- ^ “3.10.1 Documentation » The Python Language Reference » 3. Data model ¶3.2. The standard type hierarchy” (2021年12月16日). 2021年12月16日閲覧。
レンジ[編集]
レンジ( range )は、等差数列を表すシーケンスです[1]。
コンストラクター[編集]
レンジにリテラルはありません。 コンストラクターである組込み関数 range()を使って生成します。
- コンストラクター
print(f"""\ {range(5)=} {range(2,20)=} {range(2,20,3)=} {list(range(5))=} {list(range(2,20))=} {list(range(2,20,3))=} """)
- 実行結果
range(5)=range(0, 5) range(2,20)=range(2, 20) range(2,20,3)=range(2, 20, 3) list(range(5))=[0, 1, 2, 3, 4] list(range(2,20))=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] list(range(2,20,3))=[2, 5, 8, 11, 14, 17]
- range関数の引数は変則的で、1つの場合はstart=0が仮定されます(str()・repr()・print()などで文字列化すると隠れた0が現れます)
レンジと演算子[編集]
- レンジと演算子
rng = range(2,50,3) print(f'''\ {rng=} {list(rng)=} {rng.start=} {rng.stop=} {rng.step=} {rng[1]=} {rng[-1]=} {rng[2:10:2]=} {list(rng[2:10:2])=} {rng[2:10]=} {list(rng[2:10])=} {rng[:10]=} {list(rng[:10])=} {rng[2:]=} {list(rng[2:])=} {rng == range(2,24,3)=} {rng != range(2,24,3)=} {7 in rng=} ''')
- 実行結果
rng=range(2, 50, 3) list(rng)=[2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47] rng.start=2 rng.stop=50 rng.step=3 rng[1]=5 rng[-1]=47 rng[2:10:2]=range(8, 32, 6) list(rng[2:10:2])=[8, 14, 20, 26] rng[2:10]=range(8, 32, 3) list(rng[2:10])=[8, 11, 14, 17, 20, 23, 26, 29] rng[:10]=range(2, 32, 3) list(rng[:10])=[2, 5, 8, 11, 14, 17, 20, 23, 26, 29] rng[2:]=range(8, 50, 3) list(rng[2:])=[8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47] rng == range(2,24,3)=False rng != range(2,24,3)=True 7 in rng=False
- レンジの要素は、インデックス演算子で参照できます。
- レンジ内の要素の順位はタプルやレンジと同じく、0番から始まります。
- 負のインデクスiは、
len(self)+i
を表します。 - レンジにスライス記法を適用すると、レンジが返ります。
- レンジ同士は、比較ができます。
- 整数がレンジに含まれるかは、in演算子で検査できます。
for文との組み合わせ[編集]
レンジは、for文の対象となるシーケンスとして使えます(これが一番一般的な使用例でしょう)。
- コード例
for i in range(5): print(i)
- 実行結果
0 1 2 3 4
レンジのフィールド一覧[編集]
- レンジのフィールド一覧
obj = range(5) for i in dir(obj): print(i, eval(f"type({obj}.{i})"))
- 実行結果
__bool__ <class 'method-wrapper'> __class__ <class 'type'> __contains__ <class 'method-wrapper'> __delattr__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'method-wrapper'> __gt__ <class 'method-wrapper'> __hash__ <class 'method-wrapper'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __reversed__ <class 'builtin_function_or_method'> __setattr__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> count <class 'builtin_function_or_method'> index <class 'builtin_function_or_method'> start <class 'int'> step <class 'int'> stop <class 'int'>
脚註[編集]
- ^ “3.10.1 Documentation » The Python Standard Library » Built-in Types” (2021年12月16日). 2021年12月16日閲覧。
Array[編集]
array モジュールは、同一の型の要素をもつシーケンスを提供します[1]。 JavaScript の TypedArray や、C言語等の静的型付けの言語の配列に相当します。
コンストラクター[編集]
arrayオブジェクトは、arrayモジュールのarray() です。
- 関数定義
def array(typecode, [inittialize-iteratable]):
arrayのtypecodeと特性 typecode C言語の型 要素のバイト数 'b' signed char 1 'B' unsigned char 1 'u' wchar_t 4 'h' signed short 2 'H' unsigned short 2 'i' signed int 4 'I' unsigned int 4 'l' signed long 8 'L' unsigned long 8 'q' signed long long 8 'Q' unsigned long long 8 'f' float 4 'd' double 8
from array import array, typecodes print("""\ {| class="wikitable" |+ arrayのtypecodeと特性 !typecode!!C言語の型!!要素のバイト数\ """) for typecode, ctype in zip(typecodes, "signed char,unsigned char,wchar_t,signed short,unsigned short,signed int,unsigned int,signed long,unsigned long,signed long long,unsigned long long,float,double".split(",")): ary = array(typecode, "ABCDEF" if typecode == 'u' else range(10)) print(f'''\ |- ! {repr(typecode)} | {ctype} |style='text-align:right'| {ary.itemsize}\ ''') print("|}")
- コンストラクター
from array import array, typecodes for typecode in typecodes: ary = array(typecode, "ABCDEF" if typecode == 'u' else range(10)) print(f'''\ {ary.typecode=} type={type(ary[0]).__name__} {ary.itemsize=} {ary=} {len(ary)=} {ary[3]=} {ary[1:-2]=} {ary[1:-2:2]=} {list(ary)=} {ary.tolist()=} ''')
- 実行結果
ary.typecode='b' type=int ary.itemsize=1 ary=array('b', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('b', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('b', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='B' type=int ary.itemsize=1 ary=array('B', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('B', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('B', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='u' type=str ary.itemsize=4 ary=array('u', 'ABCDEF') len(ary)=6 ary[3]='D' ary[1:-2]=array('u', 'BCD') ary[1:-2:2]=array('u', 'BD') list(ary)=['A', 'B', 'C', 'D', 'E', 'F'] ary.tolist()=['A', 'B', 'C', 'D', 'E', 'F'] ary.typecode='h' type=int ary.itemsize=2 ary=array('h', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('h', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('h', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='H' type=int ary.itemsize=2 ary=array('H', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('H', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('H', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='i' type=int ary.itemsize=4 ary=array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('i', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('i', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='I' type=int ary.itemsize=4 ary=array('I', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('I', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('I', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='l' type=int ary.itemsize=8 ary=array('l', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('l', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('l', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='L' type=int ary.itemsize=8 ary=array('L', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('L', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('L', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='q' type=int ary.itemsize=8 ary=array('q', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('q', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('q', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='Q' type=int ary.itemsize=8 ary=array('Q', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) len(ary)=10 ary[3]=3 ary[1:-2]=array('Q', [1, 2, 3, 4, 5, 6, 7]) ary[1:-2:2]=array('Q', [1, 3, 5, 7]) list(ary)=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.tolist()=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ary.typecode='f' type=float ary.itemsize=4 ary=array('f', [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) len(ary)=10 ary[3]=3.0 ary[1:-2]=array('f', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) ary[1:-2:2]=array('f', [1.0, 3.0, 5.0, 7.0]) list(ary)=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] ary.tolist()=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] ary.typecode='d' type=float ary.itemsize=8 ary=array('d', [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) len(ary)=10 ary[3]=3.0 ary[1:-2]=array('d', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) ary[1:-2:2]=array('d', [1.0, 3.0, 5.0, 7.0]) list(ary)=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] ary.tolist()=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
arrayと演算子[編集]
- arrayと演算子
from array import array for code in ('b', 'i', 'd'): ary = array(code, [i for i in range(10)]) print(f'''\ {type(ary)=} {ary=} {ary+ary=} {ary*3=} {3*ary=} ''')
- 実行結果
li=[10, 'ABC', 30] li[1]='ABC' li[-1]=30 li + [2,3,4]=[10, 'ABC', 30, 2, 3, 4] li * 2=[10, 'ABC', 30, 10, 'ABC', 30] 2 * li=[10, 'ABC', 30, 10, 'ABC', 30] li == [10 ,"ABC" ,30]=True li != [10 ,"ABC" ,30]=False li < [10 ,"ABC" ,30]=False li > [10 ,"ABC" ,30]=False
- arrayの要素は、インデックス演算子で参照できます。
- array内の要素の順位はタプルやレンジと同じく、0番から始まります。
- 負のインデクスiは、
len(self)+i
を表します。 - array同士の足し算は、連結した新しいarrayを返します。
- arraytと整数nとの乗算は、tをn回繰り返したarrayを返します。
- 整数nとarraytとの乗算は、tをn回繰り返したarrayを返します。
- array同士は、比較や大小判別ができます。
arrayはミュータブル[編集]
arrayの各要素を、代入・置き換えすることもできます。
- arrayはミュータブル
from array import array for code in ('b', 'i', 'd'): ary = array(code, [i for i in range(10)]) ary[8] = 100 print(f'''\ {type(ary)=} {ary=} ''')
- 実行結果
type(ary)=<class 'array.array'> ary=array('b', [0, 1, 2, 3, 4, 5, 6, 7, 100, 9]) type(ary)=<class 'array.array'> ary=array('i', [0, 1, 2, 3, 4, 5, 6, 7, 100, 9]) type(ary)=<class 'array.array'> ary=array('d', [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 100.0, 9.0])
arrayのフィールド一覧[編集]
- arrayのフィールド一覧
from array import array for code in ('b', 'i', 'd'): ary = array(code, [i for i in range(10)]) print(f'''\ {type(ary)=} {ary=} ''') for i in dir(ary): print(i, eval(f"type({ary}.{i})"))
- 実行結果
type(ary)=<class 'array.array'> ary=array('b', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) __add__ <class 'method-wrapper'> __class__ <class 'type'> __contains__ <class 'method-wrapper'> __copy__ <class 'builtin_function_or_method'> __deepcopy__ <class 'builtin_function_or_method'> __delattr__ <class 'method-wrapper'> __delitem__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'method-wrapper'> __gt__ <class 'method-wrapper'> __hash__ <class 'NoneType'> __iadd__ <class 'method-wrapper'> __imul__ <class 'method-wrapper'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __mul__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __rmul__ <class 'method-wrapper'> __setattr__ <class 'method-wrapper'> __setitem__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> append <class 'builtin_function_or_method'> buffer_info <class 'builtin_function_or_method'> byteswap <class 'builtin_function_or_method'> count <class 'builtin_function_or_method'> extend <class 'builtin_function_or_method'> frombytes <class 'builtin_function_or_method'> fromfile <class 'builtin_function_or_method'> fromlist <class 'builtin_function_or_method'> fromstring <class 'builtin_function_or_method'> fromunicode <class 'builtin_function_or_method'> index <class 'builtin_function_or_method'> insert <class 'builtin_function_or_method'> itemsize <class 'int'> pop <class 'builtin_function_or_method'> remove <class 'builtin_function_or_method'> reverse <class 'builtin_function_or_method'> tobytes <class 'builtin_function_or_method'> tofile <class 'builtin_function_or_method'> tolist <class 'builtin_function_or_method'> tostring <class 'builtin_function_or_method'> tounicode <class 'builtin_function_or_method'> typecode <class 'str'> type(ary)=<class 'array.array'> ary=array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) __add__ <class 'method-wrapper'> __class__ <class 'type'> __contains__ <class 'method-wrapper'> __copy__ <class 'builtin_function_or_method'> __deepcopy__ <class 'builtin_function_or_method'> __delattr__ <class 'method-wrapper'> __delitem__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'method-wrapper'> __gt__ <class 'method-wrapper'> __hash__ <class 'NoneType'> __iadd__ <class 'method-wrapper'> __imul__ <class 'method-wrapper'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __mul__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __rmul__ <class 'method-wrapper'> __setattr__ <class 'method-wrapper'> __setitem__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> append <class 'builtin_function_or_method'> buffer_info <class 'builtin_function_or_method'> byteswap <class 'builtin_function_or_method'> count <class 'builtin_function_or_method'> extend <class 'builtin_function_or_method'> frombytes <class 'builtin_function_or_method'> fromfile <class 'builtin_function_or_method'> fromlist <class 'builtin_function_or_method'> fromstring <class 'builtin_function_or_method'> fromunicode <class 'builtin_function_or_method'> index <class 'builtin_function_or_method'> insert <class 'builtin_function_or_method'> itemsize <class 'int'> pop <class 'builtin_function_or_method'> remove <class 'builtin_function_or_method'> reverse <class 'builtin_function_or_method'> tobytes <class 'builtin_function_or_method'> tofile <class 'builtin_function_or_method'> tolist <class 'builtin_function_or_method'> tostring <class 'builtin_function_or_method'> tounicode <class 'builtin_function_or_method'> typecode <class 'str'> type(ary)=<class 'array.array'> ary=array('d', [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) __add__ <class 'method-wrapper'> __class__ <class 'type'> __contains__ <class 'method-wrapper'> __copy__ <class 'builtin_function_or_method'> __deepcopy__ <class 'builtin_function_or_method'> __delattr__ <class 'method-wrapper'> __delitem__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'method-wrapper'> __gt__ <class 'method-wrapper'> __hash__ <class 'NoneType'> __iadd__ <class 'method-wrapper'> __imul__ <class 'method-wrapper'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __mul__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __rmul__ <class 'method-wrapper'> __setattr__ <class 'method-wrapper'> __setitem__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> append <class 'builtin_function_or_method'> buffer_info <class 'builtin_function_or_method'> byteswap <class 'builtin_function_or_method'> count <class 'builtin_function_or_method'> extend <class 'builtin_function_or_method'> frombytes <class 'builtin_function_or_method'> fromfile <class 'builtin_function_or_method'> fromlist <class 'builtin_function_or_method'> fromstring <class 'builtin_function_or_method'> fromunicode <class 'builtin_function_or_method'> index <class 'builtin_function_or_method'> insert <class 'builtin_function_or_method'> itemsize <class 'int'> pop <class 'builtin_function_or_method'> remove <class 'builtin_function_or_method'> reverse <class 'builtin_function_or_method'> tobytes <class 'builtin_function_or_method'> tofile <class 'builtin_function_or_method'> tolist <class 'builtin_function_or_method'> tostring <class 'builtin_function_or_method'> tounicode <class 'builtin_function_or_method'> typecode <class 'str'>
脚註[編集]
- ^ “3.10.1 Documentation » The Python Standard Library » Data Types » array — Efficient arrays of numeric values” (2021年12月16日). 2021年12月16日閲覧。
辞書[編集]
Pythonの辞書(Dictionary)は、任意個のキーとコレクションです。
コンストラクターとリテラル[編集]
- リストリテラル
print(f"""\ { {}=} { dict()=} { dict(((1, 1),(2, 4),(3,9)))=} { dict((i,2**i) for i in range(5))=} { {i:2**i for i in range(5)}=} { {10,"ABC", 20, "XYZ"}=} { {1:"one", 2:"two",3:"three"}=} { { 1: "壱", 2: "弐", 3: "参" }=} """)
- 実行結果
{}={} dict()={} dict(((1, 1),(2, 4),(3,9)))={1: 1, 2: 4, 3: 9} dict((i,2**i) for i in range(5))={0: 1, 1: 2, 2: 4, 3: 8, 4: 16} {i:2**i for i in range(5)}={0: 1, 1: 2, 2: 4, 3: 8, 4: 16} {10,"ABC", 20, "XYZ"}={10, 'XYZ', 'ABC', 20} {1:"one", 2:"two",3:"three"}={1: 'one', 2: 'two', 3: 'three'} { 1: "壱", 2: "弐", 3: "参" }={1: '壱', 2: '弐', 3: '参'}
- 空の辞書は、空の辞書リテラル
{}
あるいはコンストラクターである組込み関数dict()
を引数無しで呼出し生成します。 - dict()の引数は、キーと値をを要素とするコレクションを要素とするコレクションです(文章だとややこしいですが、
dict(((1, 1),(2, 4),(3,9)))=={1: 1, 2: 4, 3: 9}
です)。 - dict()には、ジェネレーション式などのイテレーターを渡す事もできます(
dict((i,2**i) for i in range(5))=={0: 1, 1: 2, 2: 4, 3: 8, 4: 16}
) - 辞書にも内包表記があります(
{i:2**i for i in range(5)}=={0: 1, 1: 2, 2: 4, 3: 8, 4: 16}
)。 - 辞書リテラルは、キーと値を : で区切ったペアをカンマ , で区切り、全体を { } で囲みます(: を , と間違えると(エラーにならず)セット(集合)のリテラルになり、気が付き遅れがちです。逆に
{}
を空集合∅のつもりで書き、辞書であることに気づかないケースもあります)。
キーの重複[編集]
Pythonでは、辞書のキーの重複は許されず、最後の値で上書きされます。 これは辞書リテラルにも当てはまり、同じキーの最も右の値がリテラル内のキーの値となります[1]。
- キーが重複した辞書リテラル
# 国語が重複している dic = {"国語": 80, "氏名": "山田タロウ", "国語": 70 } print(dic["国語"]) print(dic)
- 実行結果
70 {'国語': 70, '氏名': '山田タロウ'}
- Pythinの辞書は順位を保存するので、重複したキーの効果の痕跡が順位に出ています。
辞書のフィールド一覧[編集]
- 辞書のフィールド一覧
obj = dict() for i in dir(obj): print(i, eval(f"type({obj}.{i})"))
- 実行結果
__class__ <class 'type'> __contains__ <class 'builtin_function_or_method'> __delattr__ <class 'method-wrapper'> __delitem__ <class 'method-wrapper'> __dir__ <class 'builtin_function_or_method'> __doc__ <class 'str'> __eq__ <class 'method-wrapper'> __format__ <class 'builtin_function_or_method'> __ge__ <class 'method-wrapper'> __getattribute__ <class 'method-wrapper'> __getitem__ <class 'builtin_function_or_method'> __gt__ <class 'method-wrapper'> __hash__ <class 'NoneType'> __init__ <class 'method-wrapper'> __init_subclass__ <class 'builtin_function_or_method'> __iter__ <class 'method-wrapper'> __le__ <class 'method-wrapper'> __len__ <class 'method-wrapper'> __lt__ <class 'method-wrapper'> __ne__ <class 'method-wrapper'> __new__ <class 'builtin_function_or_method'> __reduce__ <class 'builtin_function_or_method'> __reduce_ex__ <class 'builtin_function_or_method'> __repr__ <class 'method-wrapper'> __reversed__ <class 'builtin_function_or_method'> __setattr__ <class 'method-wrapper'> __setitem__ <class 'method-wrapper'> __sizeof__ <class 'builtin_function_or_method'> __str__ <class 'method-wrapper'> __subclasshook__ <class 'builtin_function_or_method'> clear <class 'builtin_function_or_method'> copy <class 'builtin_function_or_method'> fromkeys <class 'builtin_function_or_method'> get <class 'builtin_function_or_method'> items <class 'builtin_function_or_method'> keys <class 'builtin_function_or_method'> pop <class 'builtin_function_or_method'> popitem <class 'builtin_function_or_method'> setdefault <class 'builtin_function_or_method'> update <class 'builtin_function_or_method'> values <class 'builtin_function_or_method'>
脚註[編集]
- ^ “Python 3.10.6 Documentation » The Python Language Reference » 6. Expressions » 6.2.7. Dictionary displays”. 2022年8月10日閲覧。 “If a comma-separated sequence of key/datum pairs is given, they are evaluated from left to right to define the entries of the dictionary: each key object is used as a key into the dictionary to store the corresponding datum. This means that you can specify the same key multiple times in the key/datum list, and the final dictionary’s value for that key will be the last one given.
カンマで区切られた一連のキー/データペアが与えられると、それらは左から右へと評価されて辞書のエントリーを定義します。各キーオブジェクトは、対応するデータを格納する辞書のキーとして使用されます。つまり、key/datumリストで同じキーを複数回指定しても、そのキーに対する最終的な辞書の値は、最後に指定されたものになります。”
セット[編集]
セット(set; 集合)は、一意で不変のオブジェクトの、順不同の有限集合を表します。 そのため、どのような添え字でもインデックスを付けることはできません。 しかし、反復処理することは可能で、組込み関数len() は、セット内のアイテムの数を返します。 集合の一般的な用途は、高速なメンバーシップテスト、シーケンスからの重複の除去、および交叉、和集合、差集合、対称差などの数学的操作の計算です[1]。
コンストラクターとリテラルと内包表記[編集]
- コンストラクターとリテラル
print(f'''\ { set()=} { set([10,20,30,10])=} { set(range(10))=} { {10, "ABC", 30}=} { {i for i in range(10)}=} { {(1,"one"), (2,"two"),(3,"three"),(1,"one")}=} { { (1,"壱"), (2,"弐"), (3,"参"), (1,"壱"), }=} { {1,6,2,4,2,6,2,3}=}\ ''')
- 実行結果
set()=set() set([10,20,30,10])={10, 20, 30} set(range(10))={0, 1, 2, 3, 4, 5, 6, 7, 8, 9} {10, "ABC", 30}={'ABC', 10, 30} {i for i in range(10)}={0, 1, 2, 3, 4, 5, 6, 7, 8, 9} {(1,"one"), (2,"two"),(3,"three"),(1,"one")}={(3, 'three'), (2, 'two'), (1, 'one')} { (1,"壱"), (2,"弐"), (3,"参"), (1,"壱"), }={(3, '参'), (1, '壱'), (2, '弐')} {1,6,2,4,2,6,2,3}={1, 2, 3, 4, 6}
- 空のセットは、コンストラクターである組込み関数setを引数無しで呼び出し生成します({}は辞書になります)。
- コンストラクターにイテレータブルオブジェクトを渡すと、イテレータブルオブジェクトの要素の集合をかえします(この場合も重複排除が働きます)。
- セットリテラルは、要素をカンマ , で区切り全体を波括弧 { } で囲みます。
- セットにも内包表記があり、
{ 式 for 変数 in イテレーター }
の形式です。
セットと演算子[編集]
- セットと演算子
s1 = {10, "ABC", 30} print( f"""\ {s1=} {s1 - {10, 20, 30}=} {s1 | {2, 3, 4}=} {s1 & {10, 20, 30}=} {s1 ^ {10, 20, 30}=} {s1 == {10 ,"ABC" ,30}=} {s1 != {10 ,"ABC" ,30}=} {s1 > {10 ,"ABC" ,30}=} {s1 < {10 ,"ABC" ,30}=} """ )
- 実行結果
s1={10, 'ABC', 30} s1 - {10, 20, 30}={'ABC'} s1 | {2, 3, 4}={2, 3, 'ABC', 4, 10, 30} s1 & {10, 20, 30}={10, 30} s1 ^ {10, 20, 30}={20, 'ABC'} s1 == {10 ,"ABC" ,30}=True s1 != {10 ,"ABC" ,30}=False s1 > {10 ,"ABC" ,30}=False s1 < {10 ,"ABC" ,30}=False
- セット同士の減算は、差集合を返します。
- セット同士の論理和( + や or ではなく | )は、和集合を返します。
- セット同士の論理積( * や and ではなく & )は、交叉を返します。
- セット同士の排他的論理和( xor ではなく ^ )は、対称差を返します。
- セット同士は、比較や大小判別ができます。
演算子形式とメソッド形式[編集]
- 演算子形式とメソッド形式
s = {i for i in range(10)} e = {i for i in range(10) if i % 2 == 0} o = {i for i in range(10) if i % 2 != 0} print(f"""\ { s=} { e=} { o=} { len(s)=} # 集合の濃度 { 3 in s=} # 3は集合sに含まれるか { 10 not in s=} # 10は集合sに含まれ**ない**か { e | o == s =} # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? { e.union(o) == s =} # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? { {0,3,6,9}.union({1,4,7}, {2,5,8}) == s =} # unionは2つ以上引数を持てる { s - e == o =} # 0..9と0..9の偶数の差集合は、0..9の奇数に等しいか? { s.difference(e) == o =} # 0..9と0..9の偶数の差集合は、0..9の奇数に等しいか? { s.difference(e,o) =} # differenceは2つ以上引数を持てる { e ^ o == s =} # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? { e.symmetric_difference(o) == s =} # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? { {1,3,5}.isdisjoint({2,4,6})=} # 共通要素がない { {1,2,3}.isdisjoint({2,4,6})=} # 要素2が共通 { e.issubset(s)=} # eはsの部分集合 { e <= s=} # eはsの部分集合? { e < s=} # eはsの真部分集合? { o < s=} # oはsの真部分集合? { o | e < s=} # oとeの和集合はsの真部分集合?\ """)
- 実行結果
s={0, 1, 2, 3, 4, 5, 6, 7, 8, 9} e={0, 2, 4, 6, 8} o={1, 3, 5, 7, 9} len(s)=10 # 集合の濃度 3 in s=True # 3は集合sに含まれるか 10 not in s=True # 10は集合sに含まれ**ない**か e | o == s =True # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? e.union(o) == s =True # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? {0,3,6,9}.union({1,4,7}, {2,5,8}) == s =True # unionは2つ以上引数を持てる s - e == o =True # 0..9と0..9の偶数の差集合は、0..9の奇数に等しいか? s.difference(e) == o =True # 0..9と0..9の偶数の差集合は、0..9の奇数に等しいか? s.difference(e,o) =set() # differenceは2つ以上引数を持てる e ^ o == s =True # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? e.symmetric_difference(o) == s =True # 0..9の偶数と0..9の奇数の和集合は、0..9に等しいか? {1,3,5}.isdisjoint({2,4,6})=True # 共通要素がない {1,2,3}.isdisjoint({2,4,6})=False # 要素2が共通 e.issubset(s)=True # eはsの部分集合 e <= s=True # eはsの部分集合? e < s=True # eはsの真部分集合? o < s=True # oはsの真部分集合? o | e < s=False # oとeの和集合はsの真部分集合?
メソッド keys(), values(), items()の返すオブジェクト[編集]
keys(), values(), items()の返すオブジェクトは、それぞれキー、値、キーと値のペアーのタプルのイテレータブルですが、関数から返った値は辞書とその後も結びついています(これらのオブジェクトをセット・ビュー オブジェクトと呼びます)。 リストのように静的なオブジェクトではありません。
- メソッド keys(), values(), items()の返す値
a = { 1:"one",2:"two", 3:"three"} k = a.keys() v = a.values() i = a.items() print(f"{a=}\n{k=}\n{v=}\n{i=}\n") a[0] = "zero" print(f"{a=}\n{k=}\n{v=}\n{i=}\n") del a[1] print(f"{a=}\n{k=}\n{v=}\n{i=}\n")
- 実行結果
a={1: 'one', 2: 'two', 3: 'three'} k=dict_keys([1, 2, 3]) v=dict_values(['one', 'two', 'three']) i=dict_items([(1, 'one'), (2, 'two'), (3, 'three')]) a={1: 'one', 2: 'two', 3: 'three', 0: 'zero'} k=dict_keys([1, 2, 3, 0]) v=dict_values(['one', 'two', 'three', 'zero']) i=dict_items([(1, 'one'), (2, 'two'), (3, 'three'), (0, 'zero')]) a={2: 'two', 3: 'three', 0: 'zero'} k=dict_keys([2, 3, 0]) v=dict_values(['two', 'three', 'zero']) i=dict_items([(2, 'two'), (3, 'three'), (0, 'zero')])
破壊的メソッド[編集]
破壊的メソッドは、レシーバーであるセットオブジェクト自体を変更するメソッドです。
- 破壊的メソッド
a = {1,2,3} print(f"a = {1,2,3}\n{ a=}") a.add(4) print(f"a.add(4)\n {a=}") a.remove(2) print(f"a.remove(2)\n {a=}") try: a.remove(0) print(f"a.remove(0)\n {a=}") except KeyError as e: print(type(e).__name__, e) a.discard(0) print(f"a.discard(0)\n {a=}") b = a.copy() print(f"b = a.copy()\n {b=}") try: while True: print(f"{a.pop()}", end=", ") except KeyError as e: print(type(e).__name__, e) print(f" {a=}, {b=}") b.clear() print(f"b.clear()\n {b=}")
- 実行結果
a = (1, 2, 3) a={1, 2, 3} a.add(4) a={1, 2, 3, 4} a.remove(2) a={1, 3, 4} KeyError 0 a.discard(0) a={1, 3, 4} b = a.copy() b={1, 3, 4} 1, 3, 4, KeyError 'pop from an empty set' a=set(), b={1, 3, 4} b.clear() b=set()
セットのフィールド一覧[編集]
- セットのフィールド一覧
obj = set() for i in dir(obj): print(i, eval(f"type({obj}.{i}).__name__"), eval(f"({obj}.{i}).__doc__"), sep=", " )
- 実行結果
__and__, method-wrapper, Return self&value. __class__, type, set() -> new empty set object set(iterable) -> new set object Build an unordered collection of unique elements. __contains__, builtin_function_or_method, x.__contains__(y) <==> y in x. __delattr__, method-wrapper, Implement delattr(self, name). __dir__, builtin_function_or_method, Default dir() implementation. __doc__, str, str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'. __eq__, method-wrapper, Return self==value. __format__, builtin_function_or_method, Default object formatter. __ge__, method-wrapper, Return self>=value. __getattribute__, method-wrapper, Return getattr(self, name). __gt__, method-wrapper, Return self>value. __hash__, NoneType, None __iand__, method-wrapper, Return self&=value. __init__, method-wrapper, Initialize self. See help(type(self)) for accurate signature. __init_subclass__, builtin_function_or_method, This method is called when a class is subclassed. The default implementation does nothing. It may be overridden to extend subclasses. __ior__, method-wrapper, Return self|=value. __isub__, method-wrapper, Return self-=value. __iter__, method-wrapper, Implement iter(self). __ixor__, method-wrapper, Return self^=value. __le__, method-wrapper, Return self<=value. __len__, method-wrapper, Return len(self). __lt__, method-wrapper, Return self<value. __ne__, method-wrapper, Return self!=value. __new__, builtin_function_or_method, Create and return a new object. See help(type) for accurate signature. __or__, method-wrapper, Return self|value. __rand__, method-wrapper, Return value&self. __reduce__, builtin_function_or_method, Return state information for pickling. __reduce_ex__, builtin_function_or_method, Helper for pickle. __repr__, method-wrapper, Return repr(self). __ror__, method-wrapper, Return value|self. __rsub__, method-wrapper, Return value-self. __rxor__, method-wrapper, Return value^self. __setattr__, method-wrapper, Implement setattr(self, name, value). __sizeof__, builtin_function_or_method, S.__sizeof__() -> size of S in memory, in bytes __str__, method-wrapper, Return str(self). __sub__, method-wrapper, Return self-value. __subclasshook__, builtin_function_or_method, Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached). __xor__, method-wrapper, Return self^value. add, builtin_function_or_method, Add an element to a set. This has no effect if the element is already present. clear, builtin_function_or_method, Remove all elements from this set. copy, builtin_function_or_method, Return a shallow copy of a set. difference, builtin_function_or_method, Return the difference of two or more sets as a new set. (i.e. all elements that are in this set but not the others.) difference_update, builtin_function_or_method, Remove all elements of another set from this set. discard, builtin_function_or_method, Remove an element from a set if it is a member. If the element is not a member, do nothing. intersection, builtin_function_or_method, Return the intersection of two sets as a new set. (i.e. all elements that are in both sets.) intersection_update, builtin_function_or_method, Update a set with the intersection of itself and another. isdisjoint, builtin_function_or_method, Return True if two sets have a null intersection. issubset, builtin_function_or_method, Report whether another set contains this set. issuperset, builtin_function_or_method, Report whether this set contains another set. pop, builtin_function_or_method, Remove and return an arbitrary set element. Raises KeyError if the set is empty. remove, builtin_function_or_method, Remove an element from a set; it must be a member. If the element is not a member, raise a KeyError. symmetric_difference, builtin_function_or_method, Return the symmetric difference of two sets as a new set. (i.e. all elements that are in exactly one of the sets.) symmetric_difference_update, builtin_function_or_method, Update a set with the symmetric difference of itself and another. union, builtin_function_or_method, Return the union of sets as a new set. (i.e. all elements that are in either set.) update, builtin_function_or_method, Update a set with the union of itself and others.
脚註[編集]
- ^ “3.10.1 Documentation » The Python Language Reference » 3. Data model ¶3.2. The standard type hierarchy” (2021年12月16日). 2021年12月16日閲覧。
モジュール[編集]
モジュール化(modularization / modularize)は、全体をいくつかの構成単位に分割し、問題の規模と質を低減する分割統治法(divide-and-conquer method)の一つです。 Pythonでは、パッケージ(package)とモジュール(module)がモジュール化の実現に用いられます。 このうち、パッケージはモジュールの構造的な整理手段と考えられ、まずモジュールの用途・用法について解説し、モジュールをユーザーが定義する具体的な例も示します。
モジュールmath[編集]
平方根などの数学に関する関数を使用したい場合は、モジュールmathをインポートします。
- モジュールmathの関数「sqrt()」を使い平方根を求める
import math print(math.sqrt(2)) help(math.sqrt)
- 実行結果
1.4142135623730951 Help on built-in function sqrt in module math: sqrt(x, /) Return the square root of x.
- 構文
import モジュール名
また、インポートされた関数をつかうときは、どのモジュールに由来する関数かを、pythonが判断できるようにするために、「math.sqrt()」のように、関数の前にモジュール名を書きます。 「.」はドット記号です。つまり、「モジュール名.関数名」のような書式になります。
モジュールmathでは、三角関数や指数関数なども、使えます。三角関数の単位は、ラジアンです。
- モジュールmathの関数「sin()」を使い正弦を求める
import math print(math.sin(math.pi/4))
- 実行結果
0.7071067811865475
モジュールmathの属性一覧[編集]
- モジュールmathの属性一覧
import math mod = math print(f"""\ {{| class="wikitable" |+ {type(mod).__name__} {mod.__name__}の属性一覧 |- !属性!!値!!__doc__\ """) for k,v in vars(mod).items(): print(f"""\ |- ! {k} | {repr(v)} | {getattr(v, "__doc__").splitlines()[0]}\ """) print("|}}")
module mathの属性一覧 属性 値 __doc__ __name__ 'math' str(object=) -> str __doc__ 'This module provides access to the mathematical functions\ndefined by the C standard.' str(object=) -> str __package__ str(object=) -> str __loader__ <class '_frozen_importlib.BuiltinImporter'> Meta path import for built-in modules. __spec__ ModuleSpec(name='math', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in') The specification for a module, used for loading. acos <built-in function acos> Return the arc cosine (measured in radians) of x. acosh <built-in function acosh> Return the inverse hyperbolic cosine of x. asin <built-in function asin> Return the arc sine (measured in radians) of x. asinh <built-in function asinh> Return the inverse hyperbolic sine of x. atan <built-in function atan> Return the arc tangent (measured in radians) of x. atan2 <built-in function atan2> Return the arc tangent (measured in radians) of y/x. atanh <built-in function atanh> Return the inverse hyperbolic tangent of x. ceil <built-in function ceil> Return the ceiling of x as an Integral. copysign <built-in function copysign> Return a float with the magnitude (absolute value) of x but the sign of y. cos <built-in function cos> Return the cosine of x (measured in radians). cosh <built-in function cosh> Return the hyperbolic cosine of x. degrees <built-in function degrees> Convert angle x from radians to degrees. dist <built-in function dist> Return the Euclidean distance between two points p and q. erf <built-in function erf> Error function at x. erfc <built-in function erfc> Complementary error function at x. exp <built-in function exp> Return e raised to the power of x. expm1 <built-in function expm1> Return exp(x)-1. fabs <built-in function fabs> Return the absolute value of the float x. factorial <built-in function factorial> Find x!. floor <built-in function floor> Return the floor of x as an Integral. fmod <built-in function fmod> Return fmod(x, y), according to platform C. frexp <built-in function frexp> Return the mantissa and exponent of x, as pair (m, e). fsum <built-in function fsum> Return an accurate floating point sum of values in the iterable seq. gamma <built-in function gamma> Gamma function at x. gcd <built-in function gcd> greatest common divisor of x and y hypot <built-in function hypot> hypot(*coordinates) -> value isclose <built-in function isclose> Determine whether two floating point numbers are close in value. isfinite <built-in function isfinite> Return True if x is neither an infinity nor a NaN, and False otherwise. isinf <built-in function isinf> Return True if x is a positive or negative infinity, and False otherwise. isnan <built-in function isnan> Return True if x is a NaN (not a number), and False otherwise. isqrt <built-in function isqrt> Return the integer part of the square root of the input. ldexp <built-in function ldexp> Return x * (2**i). lgamma <built-in function lgamma> Natural logarithm of absolute value of Gamma function at x. log <built-in function log> log(x, [base=math.e]) log1p <built-in function log1p> Return the natural logarithm of 1+x (base e). log10 <built-in function log10> Return the base 10 logarithm of x. log2 <built-in function log2> Return the base 2 logarithm of x. modf <built-in function modf> Return the fractional and integer parts of x. pow <built-in function pow> Return x**y (x to the power of y). radians <built-in function radians> Convert angle x from degrees to radians. remainder <built-in function remainder> Difference between x and the closest integer multiple of y. sin <built-in function sin> Return the sine of x (measured in radians). sinh <built-in function sinh> Return the hyperbolic sine of x. sqrt <built-in function sqrt> Return the square root of x. tan <built-in function tan> Return the tangent of x (measured in radians). tanh <built-in function tanh> Return the hyperbolic tangent of x. trunc <built-in function trunc> Truncates the Real x to the nearest Integral toward 0. prod <built-in function prod> Calculate the product of all the elements in the input iterable. perm <built-in function perm> Number of ways to choose k items from n items without repetition and with order. comb <built-in function comb> Number of ways to choose k items from n items without repetition and without order. pi 3.141592653589793 Convert a string or number to a floating point number, if possible. e 2.718281828459045 Convert a string or number to a floating point number, if possible. tau 6.283185307179586 Convert a string or number to a floating point number, if possible. inf inf Convert a string or number to a floating point number, if possible. nan nan Convert a string or number to a floating point number, if possible.
モジュールrandom[編集]
サイコロの目のような、乱数をつかうには、モジュールrandomをインポートします。
- モジュールmathの関数「sqrt()」を使い乱数を得る
import random for _ in range(32): print(random.randint(1, 6), end=" ")
- 実行結果
1 2 3 1 3 6 3 3 5 6 4 5 2 1 5 2 2 2 4 4 5 1 2 6 5 5 1 2 1 5 3 5
randint(a, b)
により、a以上でb以下の整数を、不規則に表示することができます。
ローカル名前空間へのインポート[編集]
たとえばモジュールmathから、sqrtだけをローカル名前空間へインポートしたい場合、コードが次のようになります。
- mathで定義されているsqrtを全てローカル名前空間にインポート
from math import sqrt a = sqrt(2) print(a)
- 実行結果
1.4142135623730951
- 構文
from モジュール名 import インポートする識別子
- の書式により、特定の関数だけを選んでインポートできます。
- ローカル名前空間にインポートした識別子は、「math.」をつけず、そのまま「sqrt(2)」のように呼び出せます。
- mathで定義されている識別子を全てローカル名前空間にインポート
from math import * print(f"{sqrt(2)=}") print(f"{pi =}")
- 実行結果
sqrt(2)=1.4142135623730951 pi =3.141592653589793
*
を指定しても、アンダースコア _ で始まる識別子はインポートされません。
ユーザー定義モジュール[編集]
ここまでは、標準ライブラリーのモジュールを紹介してきましたが、モジュールはユーザー自身で定義することもできます。
モジュール定義[編集]
ここでは、与えられた数が素数か否かを判定するモジュール isprime を作ってみましょう。
- isprime.py
""" isprime: Determine if a given number is prime Usage: import isprime isprime.isprime(42) OR from isprime import isprime isprime(4423) """ _primes = set() _noprimes = set() def isprime(x :int) -> bool : ''' >>> isprime(2) True >>> isprime(10) False ''' if x in _primes: return True if x in _noprimes: return False if x <= 1: return False i = 2 while i*i <= x: if x%i == 0: _noprimes.add(x) return False i += 1 _primes.add(x) return True if __name__ == '__main__': assert not isprime(-1) assert not isprime(0) assert not isprime(1) assert isprime(2) assert isprime(3) assert not isprime(4) help(isprime)
- アンダースコア _ で始まる識別子は、from MODULE import * でローカル名前空間に読み込まれません。
- 過去に素数判定を行った履歴を残し、履歴に残った判定結果を再利用するためにだけ使うので、アンダースコア _ を前置してモジュール内だけで使うことを表しました[1]。
- isprimeだけがモジュール外から可視化された識別子となります。
if __name__ == '__main__':
以下は、このファイルがモジュールではなく、メインスクリプトとして実行されたときに評価され、回帰テストなどを書くことが一般的です。
モジュールのインポートと識別子を使った参照[編集]
- Main.py
import isprime hash = {} for x in range(100): hash[x] = isprime.isprime(x) print(hash) help(isprime)
- 実行結果
{0: False, 1: False, 2: True, 3: True, 4: False, 5: True, 6: False, 7: True, 8: False, 9: False, 10: False, 11: True, 12: False, 13: True, 14: False, 15: False, 16: False, 17: True, 18: False, 19: True, 20: False, 21: False, 22: False, 23: True, 24: False, 25: False, 26: False, 27: False, 28: False, 29: True, 30: False, 31: True, 32: False, 33: False, 34: False, 35: False, 36: False, 37: True, 38: False, 39: False, 40: False, 41: True, 42: False, 43: True, 44: False, 45: False, 46: False, 47: True, 48: False, 49: False, 50: False, 51: False, 52: False, 53: True, 54: False, 55: False, 56: False, 57: False, 58: False, 59: True, 60: False, 61: True, 62: False, 63: False, 64: False, 65: False, 66: False, 67: True, 68: False, 69: False, 70: False, 71: True, 72: False, 73: True, 74: False, 75: False, 76: False, 77: False, 78: False, 79: True, 80: False, 81: False, 82: False, 83: True, 84: False, 85: False, 86: False, 87: False, 88: False, 89: True, 90: False, 91: False, 92: False, 93: False, 94: False, 95: False, 96: False, 97: True, 98: False, 99: False} Help on module isprime: NAME isprime DESCRIPTION isprime: Determine if a given number is prime Usage: import isprime isprime.isprime(42) OR from isprime import isprime isprime(4423) FUNCTIONS isprime(x: int) -> bool >>> isprime(2) True >>> isprime(10) False FILE /workspace/isprime.py
- help()関数にモジュールを渡すと __docstring__ がレンダリングされます。
try節とexcept節[編集]
try と except のある構文を用いて、例外が発生した時の処理を記述できる。
try: 例外の発生する可能性のある処理 except: 例外発生時に行う処理
例外の起きそうな処理を、tryブロックに書く。tryブロック内で数値を0で割るなどの処理が発生すると、エラーとして認識され、exceptブロックの処理にうつり、exceptブロック内の処理が行われる。
try: print("3を入力した整数aで割るプログラム。") x = int(input()) a = 3 / x print(a) except: print("エラーが発生しました。")
上記のプログラムでは、もし0で割るなどの例外が発生すると、exceptブロックにある処理が実行されるので、「エラーが発生しました。」が表示される。また、print(a)が実行されるよりも先にエラーが発生するため、先にexceptブロックに処理が移るので、計算結果の3 / xは表示されない。
なお、もし正常に数値を入力するなどして、例外が発生しなければ、けっして「エラーが発生しました。」は表示されずに、3 / xの計算結果が表示される。
たとえば、入力の数値として、数「2」を入力すると、3 / 2の計算結果である「1.5」が表示され、そのままプログラムが終わる。
なお、tryブロックの外で例外が発生しても、exceptには処理は移動せずに、プログラムのエラーにより終了する。
print("3を入力した整数aで割るプログラム。") x = int(input()) a = 3 / x try: print(a) except: print("エラーが発生しました。")
たとえば、上記のプログラムで、「0」を入力すると、「エラーが発生しました。」は表示されない。0を入力してエンターキーを押した直後に、インタープリターによりエラーメッセージ「ZeroDivisionError: division by zero」などのメッセージが表示され、そしてプログラムは終了する。
else節[編集]
elseブロックの処理は、例外が発生しなかった場合に、最後に行われる処理である。
finally節[編集]
finallyブロックの処理は、例外が発生しても発生しなくても、どちらの場合にも、最後に行われる処理である。
try: print("3を入力した整数aで割るプログラム。") x = int(input()) a = 3 / x print(a) except: print("エラーが発生しました。") finally: print("計算を終了します。")
return と finally[編集]
- return と finally
def div(n, d) : try : return n / d except Exception as e: print(e) finally : print("div(%s, %s) -- finally" % (n, d)) print("div(1, 2) = %s" % div(1, 2)) print("div(1, 0) = %s" % div(1, 0)) print("div(0, 0) = %s" % div(0, 0))
- 実行結果
div(1, 2) -- finally div(1, 2) = 0.5 division by zero div(1, 0) -- finally div(1, 0) = None division by zero div(0, 0) -- finally div(0, 0) = None
- try文にfinally節を持つ言語では「tryブロックで例外を出さずのreturn文に達したとき、finally節を実行するか?」が問題になります。
- Puthonでは、return文に達してもfinally節が実行されます。
例外の場合わけ[編集]
pythonの例外処理では、生じた例外クラスに応じての場合わけもできます。
try: 例外の発生する可能性のある処理 except 例外クラスA: 例外発生時に行う処理 except 例外クラスB: 例外発生時に行う処理
のように、生じた例外クラスにおうじて、exceptのあとに例外クラスを指定します。
「ゼロで割り算できない」という例外の場合は組込み例外 ZeroDivisionError を、exceptの直後に記述することにより、例外クラスを指定します。
よって、この部分のコード記述は、
except ZeroDivisionError :
のようになります。
ほかにも例外クラスはあります。例外クラスが、型(かた)についてのエラーの場合には組込み例外 ValueErorrを、exceptの直後に記述することにより、例外クラスを指定します。なお、「型」とは、「整数型」とか「文字列型」とかのことです。
つまり、この場合の、この部分のコード記述は、
except ValueError :
のようになります。
まとめると、
try: 例外の発生する可能性のある処理 except ZeroDivisionError : ゼロで割り算したことによる例外発生の時に行う処理 except ValueError : 型のミスによる例外発生の時に行う処理 else : 例外が上がらなかったときの処理 finally : 例外の有無に関わらす実行する処理
のようになります。
なお、エラーを種類を指定するキーワードは、上記のZeroDivisionError や ValueError の他にも、たくさん、あります。
- コード例
def divide_with_exception(n, d): try: return n / d except ZeroDivisionError as e: print('catch ZeroDivisionError:', e) except TypeError as e: print('catch TypeError:', e) finally: print('finally') print("out of try block") x = divide_with_exception(1, 2) print("1 / 2 => ", x) x = divide_with_exception(1, 0) print("1 / 0 => ", x) x = divide_with_exception("ABC", 0) print('"ABC" / 0 => ', x)
- 実行結果
finally 1 / 2 => 0.5 catch ZeroDivisionError: division by zero finally out of try block 1 / 0 => None catch TypeError: unsupported operand type(s) for /: 'str' and 'int' finally out of try block "ABC" / 0 => None
- 例外が発生しなかったときも、'finally'は表示されますが、'out of try block'は例外が発生したときだけ表示されます。
- これは、例外が上がらなければそのまま return が実行され関数を終えているからです。
- 例外が上がったときの戻り値は None になっていることにも注意してください。
組込み例外一覧[編集]
__builtins__ の要素のうち BaseExceptionのサブクラスを例外とし、例外と例外の __doc__ を表にしました。
- 組込み例外一覧
#print(issubclass(ValueError, Exception)) ex = [] for k in vars(__builtins__): try: if eval(f"issubclass({k}, BaseException)"): ex.append(k) except TypeError: pass print(f"""\ {{| class=wikitable |+ 組込み例外 !例外!!__doc__\ """) for k in sorted(ex): print(f"""\ |- ! {k} | {eval(f"{k}.__doc__")}\ """) print("|}")
組込み例外 例外 __doc__ ArithmeticError Base class for arithmetic errors. AssertionError Assertion failed. AttributeError Attribute not found. BaseException Common base class for all exceptions BlockingIOError I/O operation would block. BrokenPipeError Broken pipe. BufferError Buffer error. BytesWarning Base class for warnings about bytes and buffer related problems, mostly related to conversion from str or comparing to str.
ChildProcessError Child process error. ConnectionAbortedError Connection aborted. ConnectionError Connection error. ConnectionRefusedError Connection refused. ConnectionResetError Connection reset. DeprecationWarning Base class for warnings about deprecated features. EOFError Read beyond end of file. EnvironmentError Base class for I/O related errors. Exception Common base class for all non-exit exceptions. FileExistsError File already exists. FileNotFoundError File not found. FloatingPointError Floating point operation failed. FutureWarning Base class for warnings about constructs that will change semantically in the future.
GeneratorExit Request that a generator exit. IOError Base class for I/O related errors. ImportError Import can't find module, or can't find name in module. ImportWarning Base class for warnings about probable mistakes in module imports IndentationError Improper indentation. IndexError Sequence index out of range. InterruptedError Interrupted by signal. IsADirectoryError Operation doesn't work on directories. KeyError Mapping key not found. KeyboardInterrupt Program interrupted by user. LookupError Base class for lookup errors. MemoryError Out of memory. ModuleNotFoundError Module not found. NameError Name not found globally. NotADirectoryError Operation only works on directories. NotImplementedError Method or function hasn't been implemented yet. OSError Base class for I/O related errors. OverflowError Result too large to be represented. PendingDeprecationWarning Base class for warnings about features which will be deprecated in the future.
PermissionError Not enough permissions. ProcessLookupError Process not found. RecursionError Recursion limit exceeded. ReferenceError Weak ref proxy used after referent went away. ResourceWarning Base class for warnings about resource usage. RuntimeError Unspecified run-time error. RuntimeWarning Base class for warnings about dubious runtime behavior. StopAsyncIteration Signal the end from iterator.__anext__(). StopIteration Signal the end from iterator.__next__(). SyntaxError Invalid syntax. SyntaxWarning Base class for warnings about dubious syntax. SystemError Internal error in the Python interpreter. Please report this to the Python maintainer, along with the traceback, the Python version, and the hardware/OS platform and version.
SystemExit Request to exit from the interpreter. TabError Improper mixture of spaces and tabs. TimeoutError Timeout expired. TypeError Inappropriate argument type. UnboundLocalError Local name referenced but not bound to a value. UnicodeDecodeError Unicode decoding error. UnicodeEncodeError Unicode encoding error. UnicodeError Unicode related error. UnicodeTranslateError Unicode translation error. UnicodeWarning Base class for warnings about Unicode related problems, mostly related to conversion problems.
UserWarning Base class for warnings generated by user code. ValueError Inappropriate argument value (of correct type). Warning Base class for warning categories. ZeroDivisionError Second argument to a division or modulo operation was zero.
Pythonのクラスについて学ぶことで、自分自身のデータ型を定義して、その型に基づいて作成されたオブジェクトにアクセスする方法を学ぶことができます。 このチュートリアルでは、Pythonでクラスを定義する方法、クラスオブジェクトとインスタンスオブジェクトの違い、クラス変数とインスタンス変数、メソッド、継承、プライベート変数とメソッド、プロパティ、抽象基底クラスなどのトピックについて説明します。
クラスの概要[編集]
Pythonのクラスは、オブジェクト指向プログラミングにおける基本的な概念の一つで、データと関数をまとめて扱うことができます。
クラスは、プログラム内でオブジェクトを作成するための設計図のようなものです。クラスには、そのオブジェクトが持つ属性(データ)や振る舞い(メソッド)が定義されています。クラスを定義することで、同じような性質を持ったオブジェクトを簡単に作成することができます。
クラスの中で定義されたデータは、クラス変数とインスタンス変数の2種類があります。クラス変数は、そのクラスが持つデータであり、全てのインスタンスで共有されます。インスタンス変数は、オブジェクトごとに異なる値を持つデータであり、各インスタンスごとに独立しています。
メソッドは、オブジェクトの振る舞いを定義するための関数です。クラスに定義されたメソッドは、インスタンスを通じて呼び出すことができます。
クラスは、継承を使って他のクラスを拡張することができます。継承することで、既存のクラスの機能を再利用し、新たな機能を追加することができます。
また、Pythonにはプライベート変数やプロパティ、抽象基底クラスなど、クラスをより強力にするための機能があります。これらの機能を使うことで、より柔軟で安全なコードを書くことができます。
クラスの定義方法[編集]
Pythonでは class
キーワードを使用してクラスを定義します。基本的な構文は以下の通りです。
class ClassName: # クラスの本体
クラス名は、PascalCase で書かれた単語である必要があります。クラスの本体には、変数や関数を定義することができます。
クラスを定義する[編集]
以下の例では、Person
というクラスを定義しています。このクラスには、名前と年齢のインスタンス変数、およびそれらを設定するための __init__
メソッドが含まれています。
class Person: def __init__(self, name, age): self.name = name self.age = age
このクラスを使うと、以下のようにして Person
のインスタンスを作成することができます。
person1 = Person("Alice", 25) person2 = Person("Bob", 30)
クラスオブジェクトとインスタンスオブジェクト[編集]
クラス定義によって作成されたオブジェクトには、2つの種類があります。1つはクラスオブジェクトであり、もう1つはインスタンスオブジェクトです。
クラスオブジェクト[編集]
クラスオブジェクトは、クラス定義に基づいて作成され、クラス変数にアクセスするために使用されます。
class MyClass: class_variable = 0 print(MyClass.class_variable)
この場合は、MyClass
がクラスオブジェクトです。
インスタンスオブジェクト[編集]
インスタンスオブジェクトは、クラスから作成された各オブジェクトのことを指します。それぞれのインスタンスは、独自の状態を保持できます。
class MyClass: def __init__(self): self.instance_variable = 0 my_object1 = MyClass() my_object2 = MyClass() print(my_object1.instance_variable) print(my_object2.instance_variable)
この場合は、my_object1とmy_object2 がインスタンスオブジェクトです。
- 曖昧さのない場合は、クラスオブジェクトをクラス、インスタンスオブジェクトをインスタンスと呼びます。
クラス変数とインスタンス変数[編集]
クラス変数はクラス内で定義され、すべてのインスタンスで共有される変数です。インスタンス変数は、各インスタンスごとに異なる値を持つ変数です。
クラス変数とインスタンス変数の定義[編集]
以下は、クラス変数とインスタンス変数を定義する例です。
class MyClass: class_variable = 0 # クラス変数 def __init__(self, instance_variable): self.instance_variable = instance_variable # インスタンス変数
上記の例では、class_variable
はクラス変数、instance_variable
はインスタンス変数です。class_variable
はクラス内で定義され、インスタンス作成前に定義されます。instance_variable
は、__init__
メソッド内で初期化されるため、インスタンスが作成されるたびに異なる値が割り当てられます。
クラス変数とインスタンス変数のアクセス方法[編集]
以下は、クラス変数とインスタンス変数をアクセスする例です。
class MyClass: class_variable = 0 # クラス変数 def __init__(self, instance_variable): self.instance_variable = instance_variable # インスタンス変数 my_instance = MyClass(1) print(my_instance.class_variable) # クラス変数のアクセス方法 print(my_instance.instance_variable) # インスタンス変数のアクセス方法 MyClass.class_variable = 2 # クラス変数の変更 my_other_instance = MyClass(3) print(my_other_instance.class_variable) # クラス変数の変更後のアクセス方法
上記の例では、my_instance
はMyClass
のインスタンスであり、class_variable
とinstance_variable
にアクセスしています。MyClass.class_variable
を変更すると、MyClass
のすべてのインスタンスが新しい値を持つようになります。
メソッド[編集]
Pythonにおけるメソッドとは、オブジェクトが持つ関数のことです。メソッドは、クラス内に定義された関数であり、オブジェクトに対して呼び出されることが前提となっています。
メソッドは、インスタンスメソッド、クラスメソッド、スタティックメソッド、特殊メソッドなど、種類によって様々な特徴を持っています。
インスタンスメソッドは、そのオブジェクトに対して呼び出され、クラスメソッドは、そのクラスに対して呼び出されます。
スタティックメソッドは、オブジェクトやクラスに関係なく、独立して呼び出されます。
特殊メソッドは、Pythonが提供する特別な機能を持つメソッドであり、例えば、__init__
や__str__
などがあります。
インスタンスメソッド[編集]
インスタンスメソッドは、クラスのインスタンスによって呼び出されます。第1引数は必ず self
で、それを使ってインスタンスの属性にアクセスできます。
class MyClass: def instance_method(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 print(f"Called instance_method with {self.arg1} and {self.arg2}") obj = MyClass() obj.instance_method("hello", "world") # "Called instance_method with hello and world"
このコードは、インスタンスメソッドの例です。 instance_method
は、self
を最初の引数として受け取り、その引数はメソッドが呼び出されたインスタンス自体を指します。このインスタンスを介して、メソッドはオブジェクトの状態を変更することができます。引数arg1
とarg2
は、メソッドに渡され、メソッドの処理に使用されます。
上記のコードは、MyClassのインスタンスobj
を作成し、instance_method
を呼び出しています。 instance_method
は、 obj
がインスタンスであるため、self
として自分自身を参照し、 "Called instance_method with hello and world"という文字列を出力します。
- 単にメソッドと言った場合、インスタンスメソッドを示すことが多いですが、文脈に注意しましょう。
クラスメソッド[編集]
クラスメソッドは、クラス自体によって呼び出されます。第1引数は必ず cls
で、それを使ってクラスの属性にアクセスできます。
class MyClass: class_var = "class variable" @classmethod def class_method(cls, arg): cls.arg = arg print(f"Called class_method with {cls.arg} and {cls.class_var}") MyClass.class_method("hello") # "Called class_method with hello and class variable"
上記のコードは、MyClass
というクラスを定義し、その中に class_var
というクラス変数を定義し、class_method
というクラスメソッドを定義しています。
class_method
は、@classmethod
デコレータで修飾されており、第一引数が cls
というクラスオブジェクトであることが示されています。クラスメソッドは、クラス自身を第一引数として受け取るため、クラス変数にアクセスしたい場合は、cls.class_var
のようにしてアクセスすることができます。
このクラスメソッドは、arg
という引数を受け取り、cls.arg
にその値を代入し、cls.arg
と cls.class_var
を用いてメッセージを出力するという動作をします。
最後の行では、class_method
をクラス名で呼び出しています。class_method
がクラスメソッドであるため、第一引数にはクラスオブジェクト MyClass
が自動的に渡されます。
スタティックメソッド[編集]
スタティックメソッドは、クラス自体やインスタンスから呼び出すことができます。スタティックメソッドは self
や cls
が必要ないため、第1引数を定義しません。
class MyClass: @staticmethod def static_method(arg): print(f"Called static_method with {arg}") MyClass.static_method("hello") # "Called static_method with hello"
この例では、@staticmethod
デコレータが使われています。このデコレータを使うことで、メソッドがスタティックメソッドであることを明示的に示すことができます。
スタティックメソッドはクラスに属していますが、インスタンスには属していないため、引数に self
や cls
を必要としません。そのため、スタティックメソッドは通常、インスタンス変数を使用する必要がない場合に使用されます。
上記の例では、@staticmethod
を使って static_method
メソッドを定義しています。このメソッドは arg
という引数を受け取り、"Called static_method with {arg}"
というメッセージを出力します。
最後の行では、MyClass.static_method("hello")
というコードを実行することで、static_method
メソッドを呼び出しています。この結果、"Called static_method with hello"
というメッセージが出力されます。
特殊メソッド[編集]
特殊メソッドは、Pythonによって予約されたメソッドで、オブジェクトの様々な振る舞いを定義することができます。特殊メソッドは、名前が __
で始まり、終わります。
例えば、__init__()
は、オブジェクトが作成されるときに自動的に呼び出されるメソッドで、インスタンス変数の初期化などの処理を行います。
class MyClass: def __init__(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 print(f"Called __init__ with {self.arg1} and {self.arg2}") obj = MyClass("hello", "world") # "Called __init__ with hello and world"
このコードは、MyClassという名前のクラスを定義し、__init__という特殊メソッドを使ってインスタンスを初期化しています。 __init__メソッドは、クラスがインスタンス化される際に自動的に呼び出されます。このメソッドは、インスタンスの属性を初期化するのに使用されます。 上記の例では、MyClassのインスタンスを作成し、"hello"という値をarg1に、"world"という値をarg2に割り当て、__init__メソッドが呼び出されたことを示す出力が表示されます。
は代表的な特殊メソッド メソッド名 説明 __init__(self[, ...])
インスタンスが作成されるときに呼び出される。初期化のためのメソッドで、必須の引数は self
以外にある。__str__(self)
str()
関数で呼び出される。オブジェクトを表す文字列を返す。__repr__(self)
repr()
関数で呼び出される。オブジェクトを表す公式的な文字列を返す。__len__(self)
len()
関数で呼び出される。オブジェクトの長さを返す。__getitem__(self, key)
インデックスを使用して要素を取得するために []
演算子で呼び出される。__setitem__(self, key, value)
インデックスを使用して要素を設定するために []
演算子で呼び出される。__delitem__(self, key)
インデックスを使用して要素を削除するために []
演算子で呼び出される。__contains__(self, item)
in
演算子で呼び出される。オブジェクトが指定された要素を含む場合にTrue
を返す。__call__(self[, args...])
オブジェクトが関数として呼び出されたときに呼び出される。
- この表には含まれていないが、よく使われる特殊メソッドとして
__add__()
、__sub__()
、__mul__()
、__div__()
などがあります。これらは、演算子+
、-
、*
、/
などが使われたときに呼び出されるメソッドで、オブジェクトに適切な演算子の動作を定義することができます。
Pythonのクラスのインスタンスにforを適用する |
Pythonのクラスのインスタンスに for 文を適用するには、クラスに __iter__() と __next__() メソッドを実装する必要があります。これらのメソッドを実装することで、クラスのインスタンスをイテレータとして扱うことができます。
以下は、クラスのインスタンスに
上記の例では、 |
継承[編集]
継承とは、既存のクラスを基に新しいクラスを作り出すことで、既存のクラスの機能を引き継ぎながら、新たな機能を追加することができます。
スーパークラスの定義[編集]
スーパークラスは、継承元のクラスのことを指します。スーパークラスの定義は、通常のクラス定義と同じように行います。
以下の例では、Person
というクラスをスーパークラスとして定義しています。
class Person: def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print(f"My name is {self.name} and I am {self.age} years old.")
このスーパークラス Person
は、name
と age
の属性を持ち、say_hello()
メソッドを定義しています。
サブクラスの定義[編集]
サブクラスは、スーパークラスを継承して新たなクラスを作り出すことができます。サブクラスは、新たに追加する属性やメソッドを定義することができます。
以下の例では、Student
というクラスを、スーパークラスである Person
を継承して定義しています。
class Student(Person): def __init__(self, name, age, grade): super().__init__(name, age) self.grade = grade def say_hello(self): print(f"My name is {self.name}, I am {self.age} years old and my grade is {self.grade}.")
このサブクラス Student
は、Person
クラスを継承して、grade
の属性を追加し、say_hello()
メソッドをオーバーライドしています。
オーバーライド[編集]
サブクラスでスーパークラスのメソッドを再定義することをオーバーライドと呼びます。サブクラスで同名のメソッドを定義することで、スーパークラスのメソッドを上書きすることができます。
上記の例では、Student
クラスで say_hello()
メソッドを再定義し、出力内容を変更しています。
super() 関数[編集]
サブクラスでスーパークラスのメソッドを呼び出すには、super() 関数を使用します。super() 関数を呼び出すことで、スーパークラスのメソッドを呼び出すことができます。
上記の例では、Student クラスの __init__() メソッドで、super() 関数を使用して、スーパークラスの __init__() メソッドを呼び出しています。 これにより、Person クラスで定義した name と age の属性を、Student クラスでも使用することができます。
多重継承[編集]
Python では、複数のクラスを同時に継承することができます。これを多重継承と呼びます。多重継承では、カンマで区切って複数のスーパークラスを指定します。 以下の例では、Person クラスというスーパークラスを継承し、さらに、Swimmer というクラスも同時に継承しています。
class Swimmer: def swim(self): print("I'm swimming!") class SwimmingStudent(Person, Swimmer): def __init__(self, name, age, grade): super().__init__(name, age) self.grade = grade def say_hello(self): print(f"My name is {self.name}, I am {self.age} years old and my grade is {self.grade}.") def swim(self): print("I'm swimming like a pro!") SwimmingStudent("Alice", 10, 5).swim() # => I'm swimming like a pro!
上記の例では、Swimmer クラスを定義して、swim() メソッドを持たせています。 そして、SwimmingStudent クラスで Person クラスと Swimmer クラスの両方を継承しています。 さらに、SwimmingStudent クラスで swim() メソッドをオーバーライドして、Swimmer クラスで定義した swim() メソッドと異なる動作をするようにしています。 最後に、SwimmingStudent クラスのインスタンスを作成して、swim() メソッドを呼び出した結果、Swimmer クラスで定義した swim() メソッドではなく、SwimmingStudent クラスでオーバーライドした swim() メソッドが呼び出されることが確認できます。
継承されることを想定した標準モジュールのクラス |
Pythonの標準モジュールの中で、継承を想定して設計されたクラスとしては、以下のようなものがあります。
これらのクラスは、Pythonの標準ライブラリで広く使われており、継承によってカスタマイズされたクラスを作成することができます。また、これらのクラスを継承することで、多態性の実現や、型ヒントによる静的解析などの恩恵を受けることができます。 |
プライベート変数とメソッド[編集]
プライベート変数やメソッドとは、クラスの外から直接アクセスできないようにするために用意されたものです。Pythonでは、アンダースコア(_)で始まる変数名やメソッド名を定義することで、プライベート変数やメソッドを作成することができます。
プライベート変数とメソッドの定義方法[編集]
プライベート変数を定義する場合、変数名の先頭にアンダースコアを付けます。以下の例では、Person クラスにプライベート変数 _password を定義しています。
class Person: def __init__(self, name, age, password): self.name = name self.age = age self._password = password def say_hello(self): print(f"My name is {self.name} and I am {self.age} years old.") def _show_password(self): print(f"My password is {self._password}.")
同様に、プライベートメソッドを定義する場合も、メソッド名の先頭にアンダースコアを付けます。上記の例では、Person クラスにプライベートメソッド _show_password() を定義しています。
プライベート変数とメソッドのアクセス方法[編集]
プライベート変数やメソッドは、クラスの外から直接アクセスすることができません。しかし、アクセスする方法が用意されています。
プライベート変数にアクセスする場合、変数名の前にアンダースコアを付けます。以下の例では、Person クラスのインスタンス p から、プライベート変数 _password にアクセスしています。
p = Person("Alice", 25, "password123") print(p._password) # "password123" を出力
ただし、この方法は推奨されていません。Pythonでは、アンダースコアで始まる変数やメソッドは、外部から直接アクセスしないことが慣例となっています。プライベート変数やメソッドにアクセスする場合は、公開されているインターフェースを通じて行うようにしましょう。
プライベートメソッドにアクセスする場合、同様にメソッド名の前にアンダースコアを付けます。以下の例では、Person クラスのインスタンス p から、プライベートメソッートメソッド _show_password() にアクセスしています。
p = Person("Alice", 25, "password123") p._show_password() # "My password is password123." を出力
同様に、クラス内で定義された公開メソッドを通じて、プライベート変数やメソッドにアクセスすることもできます。
以下の例では、Person クラスに公開メソッド get_password() を定義し、それを通じてプライベート変数 _password にアクセスしています。
class Person: def __init__(self, name, age, password): self.name = name self.age = age self._password = password def say_hello(self): print(f"My name is {self.name} and I am {self.age} years old.") def _show_password(self): print(f"My password is {self._password}.") def get_password(self): return self._password p = Person("Alice", 25, "password123") print(p.get_password()) # "password123" を出力
このように、Pythonでは、プライベート変数やメソッドを定義することで、クラスの外からの直接アクセスを制限することができます。 ただし、アクセスするための手段は用意されているため、必要な場合には適切に利用するようにしましょう。
プロパティ[編集]
プロパティとは、クラスの外からもアクセスできるようにしたい変数を指します。 しかし、変数に直接アクセスすると不適切な値が設定される可能性があるため、アクセス時に特定の処理を実行する必要があります。 このような場合に、プロパティを使います。
プロパティの定義方法[編集]
Pythonでは、プロパティを定義するには property
ビルトイン関数を使用します。プロパティを定義するには、以下のような方法があります。
getter関数のみを定義する場合[編集]
getter関数のみを定義する場合、以下のように @property
デコレータを使用して、getter関数にアクセスすることができます。
class Person: def __init__(self, name, age): self._name = name self._age = age @property def name(self): return self._name @property def age(self): return self._age
このように定義することで、インスタンスから以下のようにして name
や age
にアクセスすることができます。
person = Person("Alice", 25) print(person.name) # "Alice" を出力 print(person.age) # 25 を出力
getter関数とsetter関数の両方を定義する場合[編集]
getter関数とsetter関数の両方を定義する場合、以下のように @property
デコレータと @<property名>.setter
デコレータを使用して、getter関数とsetter関数にアクセスすることができます。
class Person: def __init__(self, name, age): self._name = name self._age = age @property def name(self): return self._name @name.setter def name(self, value): self._name = value @property def age(self): return self._age @age.setter def age(self, value): self._age = value
このように定義することで、インスタンスから以下のようにして name
や age
にアクセスし、変更することができます。
person = Person("Alice", 25) print(person.name) # "Alice" を出力 print(person.age) # 25 を出力 person.name = "Bob" person.age = 30 print(person.name) # "Bob" を出力 print(person.age) # 30 を出力
プロパティのアクセス方法[編集]
プロパティにアクセスする場合、通常のインスタンス変数と同様に、以下のようにしてアクセスします。
person = Person("Alice", 25) print(person.name) # "Alice" を出力 print(person.age) # 25 を出力
また、setter関数を定義している場合、以下のようにしてプロパティの値を変更することができます。
person.name = "Bob" person.age = 30 print(person.name) # "Bob" を出力 print(person.age) # 30 を出力
プロパティを使用することで、クラスの外部からもインスタンス変数にアクセスできるようになり、getter関数やsetter関数を使用することで、変数の値に対して特定の処理を行うことができます。 これにより、クラスのカプセル化が実現され、安全で信頼性の高いコードを作成することができます。
__getattr__ と __setattr__[編集]
__getattr__
と __setattr__
は Python の特殊メソッドで、オブジェクトの属性に対するアクセスをカスタマイズすることができます。
__getattr__
メソッドは、インスタンスの属性が未定義の場合に呼び出されます。通常の属性アクセスが失敗した場合に呼び出され、属性名を引数に取り、属性の値を返すように実装することができます。このメソッドを使用することで、動的な属性アクセスをサポートすることができます。
例えば、以下のようなクラス DynamicObject
を考えます。
class DynamicObject: def __getattr__(self, name): return f"{name} is not defined."
このクラスは、未定義の属性にアクセスした場合に、属性名と "is not defined." の文字列を連結したものを返します。
obj = DynamicObject() print(obj.foo) # 出力: foo is not defined.
一方、__setattr__
メソッドは、属性に値を代入する際に呼び出されます。通常の属性代入が行われた後に、属性名と代入された値を引数に取り、任意の処理を実行することができます。このメソッドを使用することで、属性代入時のチェックや変換処理を実装することができます。
例えば、以下のようなクラス PositiveNumber
を考えます。
class PositiveNumber: def __init__(self, value): self.value = value def __setattr__(self, name, value): if value < 0: raise ValueError("Value must be positive.") super().__setattr__(name, value)
このクラスは、属性に代入される値が負数である場合に、 ValueError
を発生させます。
n = PositiveNumber(1) n.value = 2 print(n.value) # 出力: 2 n.value = -1 # ValueError: Value must be positive.
- 注意点
__getattr__
メソッドや__setattr__
メソッドは、インスタンスの属性アクセスや属性代入時にのみ呼び出されます。- クラス自体にアクセスする場合には、
__getattr__
メソッドや__setattr__
メソッドは呼び出されません。 - 属性が存在する場合は
__getattr__
メソッドは呼び出されず、通常の属性アクセスが行われます。
クラス変数とインスタンス変数のプライベート化[編集]
Pythonでは、クラス変数とインスタンス変数をプライベート化することができます。プライベート変数は、クラスの外から直接アクセスすることができなくなり、情報の隠蔽や保護に役立ちます。
クラス変数とインスタンス変数のプライベート化[編集]
クラス変数とインスタンス変数をプライベート化するには、変数名の前にアンダースコア2つ(__
)をつけます。例えば、以下のように定義します。
class MyClass: __private_class_var = 10 # クラス変数のプライベート化 def __init__(self): self.__private_instance_var = 20 # インスタンス変数のプライベート化
これにより、MyClass
の外からは __private_class_var
や __private_instance_var
に直接アクセスできなくなります。ただし、Pythonでは名前修飾という仕組みがあり、アンダースコア2つを付けることで、クラス外からアクセスできなくするだけで、実際にはアクセス可能な変数として存在します。
プライベート変数のアクセス方法[編集]
プライベート変数にアクセスするためには、アンダースコア1つ(_
)を変数名の前に付けることでアクセスできます。例えば、以下のようにします。
class MyClass: __private_class_var = 10 # クラス変数のプライベート化 def __init__(self): self.__private_instance_var = 20 # インスタンス変数のプライベート化 def get_private_class_var(self): return MyClass.__private_class_var # アクセス方法 def get_private_instance_var(self): return self.__private_instance_var # アクセス方法
上記の例では、get_private_class_var()
メソッドと get_private_instance_var()
メソッドを定義し、それぞれでプライベート変数にアクセスする方法を示しています。
my_class = MyClass() print(my_class.get_private_class_var()) # 10 を出力 print(my_class.get_private_instance_var()) # 20 を出力
プライベート変数はクラスの外からアクセスできないようになっていますが、名前修飾を使用することで、直接アクセスすることができます。 ただし、名前修飾を使うことでアクセスできるようになっているため、注意が必要です。 プライベート変数は、クラス内部でしか使用しない変数であることを明確にし、情報を保護するために使用することが望ましいです。
抽象基底クラス[編集]
抽象基底クラスは、インスタンス化できない抽象的なクラスで、共通のインターフェースを定義することができます。
具体的な実装は、抽象基底クラスを継承したサブクラスで行います。
Pythonでは、抽象基底クラスを作成するために abc
モジュールを使用します。
抽象基底クラスの定義方法[編集]
抽象基底クラスを定義するには、abc.ABC
クラスを継承する必要があります。また、抽象メソッドを定義するには @abstractmethod
デコレータを使用します。
以下は、抽象基底クラスの定義例です。
import abc class MyABC(abc.ABC): @abc.abstractmethod def do_something(self): pass
上記の例では、MyABC
という抽象基底クラスを定義しています。このクラスには、do_something
という抽象メソッドが定義されています。
抽象基底クラスを継承したクラスの定義方法[編集]
抽象基底クラスを継承するサブクラスを定義する場合、@abstractmethod
で定義されたメソッドを実装する必要があります。また、抽象基底クラスを継承することで、共通のインターフェースを持つことができます。
以下は、抽象基底クラスを継承したクラスの定義例です。
class MyClass(MyABC): def do_something(self): print("MyClassの処理を実行しました")
上記の例では、MyClass
というクラスを定義し、MyABC
を継承しています。MyABC
に定義された do_something
メソッドを実装し、処理を行っています。
以上が、Pythonでの抽象基底クラスの定義方法、抽象基底クラスを継承したクラスの定義方法です。 抽象基底クラスを使用することで、共通のインターフェースを持つクラスを実装し、コードの再利用性を高めることができます。
Pythonのクラスと型アノテーション |
Pythonでは、型アノテーションを使用して関数やメソッドの引数や返り値の型を指定できますが、クラスの属性やメソッドの戻り値などでも型アノテーションを指定することができます。
例えば、以下のようにクラス定義時に属性に対して型アノテーションを指定することができます。
この例では、 また、クラス全体に対して型アノテーションを指定することもできます。例えば、以下のようにクラス定義の先頭で型アノテーションを指定することができます。
この例では、クラス定義の先頭で なお、Pythonの型アノテーションは実行時には無視されますが、型チェッカーやIDEの補完機能などで利用されます。また、Pythonの型アノテーションはオプションであるため、必ずしも指定する必要はありません。ただし、型アノテーションを指定することで、コードの読みやすさや保守性を向上させることができます。 |
Ruby からの移植[編集]
Ruby#ユーザー定義クラスをPython3に移植しました。
- Ruby からの移植
import math class GeoCoord(object): def __init__(self, longitude, latitude): self.longitude, self.latitude = longitude, latitude def __str__(self): ew, ns = "東経", "北緯" long, lat = self.longitude, self.latitude if long < 0.0: ew = "西経" long = -long if lat < 0.0: ns = "南緯" lat = -lat return f"({ew}: {long}, {ns}: {lat})" def distance(self, other): i = math.pi / 180 r = 6371.008 return ( math.acos( math.sin(self.latitude * i) * math.sin(other.latitude * i) + math.cos(self.latitude * i) * math.cos(other.latitude * i) * math.cos(self.longitude * i - other.longitude * i) ) * r ) Sites = { "東京駅": [139.7673068, 35.6809591], "シドニー・オペラハウス": [151.215278, -33.856778], "グリニッジ天文台": [-0.0014, 51.4778], } for name in Sites: Sites[name] = GeoCoord(*Sites[name]) for name in Sites: print(f"{name}: {Sites[name]}") keys, len = tuple(Sites.keys()), len(Sites) for i in range(len): x, y = keys[i], keys[(i + 1) % len] print(f"{x} - {y}: {Sites[x].distance(Sites[y])} [km]")
- 実行結果
東京駅: (東経: 139.7673068, 北緯: 35.6809591) シドニー・オペラハウス: (東経: 151.215278, 南緯: 33.856778) グリニッジ天文台: (西経: 0.0014, 北緯: 51.4778) 東京駅 - シドニー・オペラハウス: 7823.269299386704 [km] シドニー・オペラハウス - グリニッジ天文台: 16987.2708377249 [km] グリニッジ天文台 - 東京駅: 9560.546566490015 [km]
- 内包表記などを使えば、もう少し「Pythonぽい」プログラムに出来たと思いますが、なるべく一対一に移植元と対応するよう実装しました。
- end が要らないのは簡便な反面、どこで定義が終わっているか判りづらいという問題もあり、__doc__ を充実させるなど工夫が必要そうです。
- 型アノテーションは付けていません。
附録[編集]
チートシート[編集]
# クラスの定義 class MyClass: class_variable = "hello" def __init__(self, instance_variable): self.instance_variable = instance_variable def instance_method(self): print("This is an instance method.") @classmethod def class_method(cls): print("This is a class method.") @staticmethod def static_method(): print("This is a static method.") # インスタンスの生成と属性へのアクセス obj = MyClass("world") print(obj.instance_variable) print(obj.class_variable) # インスタンスメソッドの呼び出し obj.instance_method() # クラスメソッドの呼び出し MyClass.class_method() # スタティックメソッドの呼び出し MyClass.static_method() # 継承 class MySubClass(MyClass): def __init__(self, instance_variable, sub_instance_variable): super().__init__(instance_variable) self.sub_instance_variable = sub_instance_variable def sub_instance_method(self): print("This is a subclass instance method.") # プロパティの定義 class MyClass: def __init__(self, instance_variable): self._instance_variable = instance_variable @property def instance_variable(self): return self._instance_variable @instance_variable.setter def instance_variable(self, value): self._instance_variable = value # 特殊メソッド class MyClass: def __init__(self, instance_variable): self.instance_variable = instance_variable def __str__(self): return f"MyClass object: {self.instance_variable}" def __eq__(self, other): return self.instance_variable == other.instance_variable # __getattr__と__setattr__による属性のカスタマイズ class MyClass: def __init__(self, instance_variable): self._instance_variable = instance_variable def __getattr__(self, name): return f"{name} is not defined." def __setattr__(self, name, value): print(f"{name} is being set to {value}.") super().__setattr__(name, value)
用語集[編集]
- クラス(class):オブジェクト指向プログラミングにおける基本的な概念の1つで、同じ属性やメソッドを持つオブジェクトの集合を定義します。
- インスタンス(instance):クラスを元に生成されるオブジェクトのことで、独自の属性やメソッドを持ちます。
- 属性(attribute):オブジェクトが持つデータを表します。クラスの属性は全てのインスタンスで共通です。
- メソッド(method):オブジェクトが持つ振る舞いを表します。クラスのメソッドは全てのインスタンスで共通です。
- コンストラクタ(constructor):クラスからインスタンスを生成する際に、インスタンスの初期化を行うメソッドです。通常、
__init__
メソッドとして定義されます。 - 継承(inheritance):既存のクラスを基に新たなクラスを定義することで、属性やメソッドを共有することができます。
- 親クラス(superclass):継承元のクラスのことを指します。
- 子クラス(subclass):継承したクラスのことを指します。
- オーバーライド(override):子クラスが親クラスの属性やメソッドを再定義することを指します。子クラスで同名の属性やメソッドを定義することで、親クラスのものを上書きすることができます。
- 多重継承(multiple inheritance):複数のクラスから同時に継承することを指します。
- ダックタイピング(duck typing):オブジェクトの型よりも、そのオブジェクトが持つ属性やメソッドを重視するプログラミングスタイルのことを指します。
- 抽象基底クラス(abstract base class):インスタンス化できない抽象的なクラスで、共通のインターフェースを定義することができます。抽象基底クラスを作成するために abc モジュールを使用します。
- デコレータ(decorator):関数やクラスに機能を追加するための構文で、@記号で始まり、関数やクラスの前に書かれます。クラスの場合、@classmethodや@staticmethodが使用されます。
脚註[編集]
- ^ from isprime import _primes とすれば _primes としてローカル空間に現れるので、隠蔽という意味では完全ではなく、「将来の実装では参照できることを保証しません」程度の意味です(意訳:使うな!)。
型ヒント[編集]
Python は、動的型付けの言語で変数・関数の仮引数や関数の戻り値には型を指定する必要がありません(指定する方法が、従来は存在しませんでした)。
この性質は、普遍的なアルゴリズムを書くなどの用途に適していますが、たとえば、リストの値の合計を求めるつもりで書いた関数が、文字列を要素とするリストに適用さるとリストの要素を連結した文字列を返すなど、コードを書いたときの想定とは異なる使われ方をしたとき、劇的に違う実行結果を招いてしまうことがあります。
型アノテーション[編集]
Pythonにおいて、型アノテーション(Type Annotation)は変数、仮引数、戻り値などに対する型の注釈であり、Python 3.5から正式にサポートされています。型アノテーションはPythonの構文解析に含まれますが、Pythonのインタープリターによる型の検査は行われず、静的型検査を行う外部プログラム(MyPyなど)によって実行されます。これにより、コードの可読性と保守性が向上し、バグの発見や修正が容易になります。
型アノテーションのない従前のコード[編集]
- 合計のはずが連結に
def total(*args): if len(args) == 0: return 0 it = iter(args) result = next(it) for i in it: result += i return result print(f"""\ {total()=} {total(1,2,3)=} {total(*(i for i in range(10)))=} {total(*(1.0*i for i in range(10)))=} {total(False, True)=} {total("abc","def","ghi")=} {total([0,1,2],[3,4,5],[6,7,8])=}""")
- 実行結果
total()=0 total(1,2,3)=6 total(*(i for i in range(10)))=45 total(*(1.0*i for i in range(10)))=45.0 total(False, True)=1 total("abc","def","ghi")='abcdefghi' total([0,1,2],[3,4,5],[6,7,8])=[0, 1, 2, 3, 4, 5, 6, 7, 8]
型アノテーションのあるコード[編集]
- 合計のはずが連結に(オンライン実行)
- 合計のはずが連結に(mypyで検査)
from typing import Union number = Union[int, float] def total(*args: number) -> number: if len(args) == 0: return 0 it = iter(args) result = next(it) for i in it: result += i return result print(f"""\ {total()=} {total(1,2,3)=} {total(*(i for i in range(10)))=} {total(*(1.0*i for i in range(10)))=} {total(False, True)=} {total("abc","def","ghi")=} {total([0,1,2],[3,4,5],[6,7,8])=}""")
- 実行結果
- 上に同じ
- MyPyの検査結果
main.py:13: error: Argument 1 to "total" has incompatible type "str"; expected "Union[int, float]" main.py:13: error: Argument 1 to "total" has incompatible type "List[int]"; expected "Union[int, float]" main.py:13: error: Argument 2 to "total" has incompatible type "str"; expected "Union[int, float]" main.py:13: error: Argument 2 to "total" has incompatible type "List[int]"; expected "Union[int, float]" main.py:13: error: Argument 3 to "total" has incompatible type "str"; expected "Union[int, float]" main.py:13: error: Argument 3 to "total" has incompatible type "List[int]"; expected "Union[int, float]" Found 6 errors in 1 file (checked 1 source file)
- 型アノテーションを追加しても実行結果は同じですが、MyPyは6つの型の不整合を発見しています。
from typing import Union number = Union[int, float, None]
- は、python 3.9 以降では
number = int | float | None
- と、typingモジュールを頼らず書けますが、3.9より前のバージョンでは Syntax error になるので、互換性を考えると
try: number = int | float | None except TypeError as e: """ Fallback for < 3.9 """ from typing import List number = Union[int, float, None]
- の様に実行環境によって動作を変える様にできます。
- が、ここ書き方だと MyPy が2行目と6行目で型定義が重複していると警告します。
- python3.9以降でも typingモジュールは有効なので
from typing import Union number = Union[int, float, None]
- のままにしました。
型ヒント・型アノテーションは、まだ新しい機能で typing モジュールを import しない方向に進化しつつあり、今後の動向が注目されます。
__annotations__ 属性[編集]
オーブジェクトの型アノテーションについては、__annotations__ 属性によって Python プログラム中からアクセスできます。
- __annotations__ 属性
import sys print(f"{sys.version=}") v: int v = 0 print(f"{__annotations__=}") def f(a: int, b: int) -> int: _anon = f.__annotations__ assert isinstance(a,_anon["a"]) assert isinstance(b,_anon["b"]) print(f"{f.__annotations__=}") result = a + b assert isinstance(result,_anon["return"]) return result class Point(dict): x: int y: int x = 10 y = 20 print(f"{__qualname__}: {__annotations__=}") try: f(2,3) f("","") except AssertionError as err: print(f"{err=}") print("done!")
- 実行結果
sys.version='3.8.10 (default, Jun 2 2021, 10:49:15) \n[GCC 9.4.0]' __annotations__={'v': <class 'int'>} Point: __annotations__={'x': <class 'int'>, 'y': <class 'int'>} f.__annotations__={'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>} err=AssertionError() done!
- 型アノテーションは、名前の通り原則的には名前通り注釈なのですが、特殊属性 __annotations__ を介して実行中のスクリプト自身からアクセスできます。
- これを利用すると、例えば関数が実引数が仮引数の型アノテーションと一致しているかをisinstance関数で確認できます。
- isinstance関数で確認し、不一致があった場合 assert 文で AssertError をあげ、try:except で捕捉することができます。
このように、__annotations__属性を使用することで、コードの可読性や保守性を向上させることができます。ただし、__annotations__属性はPythonのランタイムには影響を与えないため、必ずしも正確である必要はありません。また、__annotations__属性を使って型チェックを行うためには、外部ライブラリを使用する必要があります。
参考文献[編集]
- “3.10.1 Documentation » The Python Standard Library » Development Tools » typing — Support for type hints” (2021年12月7日). 2021年12月7日閲覧。
- “PEP 526 -- Syntax for Variable Annotations” (2014年8月9日). 2021年12月7日閲覧。
- “PEP 484 -- Type Hints” (2014年9月29日). 2021年12月7日閲覧。
- “PEP 483 -- The Theory of Type Hints” (2014年12月19日). 2021年12月7日閲覧。
ファイルへの書込み[編集]
ファイルを書くにも読むにも、まず、そのファイルを開く必要があります。 ファイルを開くには、組込み関数 open() を使います。 もしopen()をするときにその名前のファイルがなければ、ファイルを作成されます。
- ファイルへの書込みの例
with open("create.txt", "w") as f: print("hello", file=f)
open()の2番目の引数にある「"w"」は、「書込みモード」という意味です。 open()の戻り値は f に保持されます(f の型は _io.TextIOWrapper クラスです)。
- open()の関数定義
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
ファイルに書込むには open() の戻り値 f を組込み関数 print() のキーワード引数 file に与えます。 組込み関数 print() は今まで何度も出てきましたが、キーワード引数 file には何も指定していなかったのでディフォルトの sys.stdout (標準出力)が仮定されていました。
オープンしたファイルは必ずクローズする必要があります。 この例では、with文を使っているのでブロックを抜けると自動的にクローズされます。
カレントディレクトリを見ると、「create.txt」という名のファイルが作成されており、開くと「hello」と書かれているはずです。
ファイルからの読込み[編集]
- ファイルへの一行読込みの例
with open("create.txt") as f: s = f.readline() print(s)
ここでは組込み関数 open() の第二引数『モード』を与えていませんので、ディフォルトのモード "r"(読込み)になります。 open() の戻り値 f をレシーバーにメソッド readline() を呼び出すと、ファイルから1行ずつ読み込むことができます。
上の例では、ファイルから一行だけ読み込み表示していましたが、全ての行を表示するには
- ファイルの全内容を表示する例
with open("create.txt") as f: for s in f: print(s, end='')
のように for文 を使います。 print() 関数のキーワード引数 end に を渡しているのは s には改行が含まれているため、 print() のディフォルトの動作「改行を追加する」をキャンセルするためです。
まとめのコード[編集]
- まとめのコード
with open("/workspace/hello.txt", "w") as f: for x in 'city country world universe'.split(): print(f"hello {x}", file=f) with open("/workspace/hello.txt") as f: s = f.readline() print(s) with open("/workspace/hello.txt") as f: for s in f: print(s, end='') with open("/workspace/hello.txt") as f: help(f)
- 実行結果
hello city hello city hello country hello world hello universe Help on TextIOWrapper object: class TextIOWrapper(_TextIOBase) | TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False) | | Character and line based layer over a BufferedIOBase object, buffer. | | encoding gives the name of the encoding that the stream will be | decoded or encoded with. It defaults to locale.getpreferredencoding(False). | | errors determines the strictness of encoding and decoding (see | help(codecs.Codec) or the documentation for codecs.register) and | defaults to "strict". | | newline controls how line endings are handled. It can be None, '', | '\n', '\r', and '\r\n'. It works as follows: | | * On input, if newline is None, universal newlines mode is | enabled. Lines in the input can end in '\n', '\r', or '\r\n', and | these are translated into '\n' before being returned to the | caller. If it is '', universal newline mode is enabled, but line | endings are returned to the caller untranslated. If it has any of | the other legal values, input lines are only terminated by the given | string, and the line ending is returned to the caller untranslated. | | * On output, if newline is None, any '\n' characters written are | translated to the system default line separator, os.linesep. If | newline is '' or '\n', no translation takes place. If newline is any | of the other legal values, any '\n' characters written are translated | to the given string. | | If line_buffering is True, a call to flush is implied when a call to | write contains a newline character. | | Method resolution order: | TextIOWrapper | _TextIOBase | _IOBase | builtins.object | | Methods defined here: | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | __next__(self, /) | Implement next(self). | | __repr__(self, /) | Return repr(self). | | close(self, /) | Flush and close the IO object. | | This method has no effect if the file is already closed. | | detach(self, /) | Separate the underlying buffer from the TextIOBase and return it. | | After the underlying buffer has been detached, the TextIO is in an | unusable state. | | fileno(self, /) | Returns underlying file descriptor if one exists. | | OSError is raised if the IO object does not use a file descriptor. | | flush(self, /) | Flush write buffers, if applicable. | | This is not implemented for read-only and non-blocking streams. | | isatty(self, /) | Return whether this is an 'interactive' stream. | | Return False if it can't be determined. | | read(self, size=-1, /) | Read at most n characters from stream. | | Read from underlying buffer until we have n characters or we hit EOF. | If n is negative or omitted, read until EOF. | | readable(self, /) | Return whether object was opened for reading. | | If False, read() will raise OSError. | | readline(self, size=-1, /) | Read until newline or EOF. | | Returns an empty string if EOF is hit immediately. | | reconfigure(self, /, *, encoding=None, errors=None, newline=None, line_buffering=None, write_through=None) | Reconfigure the text stream with new parameters. | | This also does an implicit stream flush. | | seek(self, cookie, whence=0, /) | Change stream position. | | Change the stream position to the given byte offset. The offset is | interpreted relative to the position indicated by whence. Values | for whence are: | | * 0 -- start of stream (the default); offset should be zero or positive | * 1 -- current stream position; offset may be negative | * 2 -- end of stream; offset is usually negative | | Return the new absolute position. | | seekable(self, /) | Return whether object supports random access. | | If False, seek(), tell() and truncate() will raise OSError. | This method may need to do a test seek(). | | tell(self, /) | Return current stream position. | | truncate(self, pos=None, /) | Truncate file to size bytes. | | File pointer is left unchanged. Size defaults to the current IO | position as reported by tell(). Returns the new size. | | writable(self, /) | Return whether object was opened for writing. | | If False, write() will raise OSError. | | write(self, text, /) | Write string to stream. | Returns the number of characters written (which is always equal to | the length of the string). | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) from builtins.type | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Data descriptors defined here: | | buffer | | closed | | encoding | Encoding of the text stream. | | Subclasses should override. | | errors | The error setting of the decoder or encoder. | | Subclasses should override. | | line_buffering | | name | | newlines | Line endings translated so far. | | Only line endings translated during reading are considered. | | Subclasses should override. | | write_through | | ---------------------------------------------------------------------- | Methods inherited from _IOBase: | | __del__(...) | | __enter__(...) | | __exit__(...) | | __iter__(self, /) | Implement iter(self). | | readlines(self, hint=-1, /) | Return a list of lines from the stream. | | hint can be specified to control the number of lines read: no more | lines will be read if the total size (in bytes/characters) of all | lines so far exceeds hint. | | writelines(self, lines, /) | Write a list of lines to stream. | | Line separators are not added, so it is usual for each of the | lines provided to have a line separator at the end. | | ---------------------------------------------------------------------- | Data descriptors inherited from _IOBase: | | __dict__
組込み関数[編集]
Pythonインタープリターには、常に利用可能な関数や型がいくつか組込まれています。
組込み関数の一覧[編集]
- 組込み関数の一覧を得るスクリプト
for x in (name for name in (dir(__builtins__)) if callable(getattr(__builtins__, name))): a = getattr(__builtins__, x) if a.__doc__ == None: continue print(x, a.__doc__.splitlines()[0], sep=": ")
- 実行例
ArithmeticError: Base class for arithmetic errors. AssertionError: Assertion failed. AttributeError: Attribute not found. BaseException: Common base class for all exceptions BlockingIOError: I/O operation would block. BrokenPipeError: Broken pipe. BufferError: Buffer error. BytesWarning: Base class for warnings about bytes and buffer related problems, mostly ChildProcessError: Child process error. ConnectionAbortedError: Connection aborted. ConnectionError: Connection error. ConnectionRefusedError: Connection refused. ConnectionResetError: Connection reset. DeprecationWarning: Base class for warnings about deprecated features. EOFError: Read beyond end of file. EnvironmentError: Base class for I/O related errors. Exception: Common base class for all non-exit exceptions. FileExistsError: File already exists. FileNotFoundError: File not found. FloatingPointError: Floating point operation failed. FutureWarning: Base class for warnings about constructs that will change semantically GeneratorExit: Request that a generator exit. IOError: Base class for I/O related errors. ImportError: Import can't find module, or can't find name in module. ImportWarning: Base class for warnings about probable mistakes in module imports IndentationError: Improper indentation. IndexError: Sequence index out of range. InterruptedError: Interrupted by signal. IsADirectoryError: Operation doesn't work on directories. KeyError: Mapping key not found. KeyboardInterrupt: Program interrupted by user. LookupError: Base class for lookup errors. MemoryError: Out of memory. ModuleNotFoundError: Module not found. NameError: Name not found globally. NotADirectoryError: Operation only works on directories. NotImplementedError: Method or function hasn't been implemented yet. OSError: Base class for I/O related errors. OverflowError: Result too large to be represented. PendingDeprecationWarning: Base class for warnings about features which will be deprecated PermissionError: Not enough permissions. ProcessLookupError: Process not found. RecursionError: Recursion limit exceeded. ReferenceError: Weak ref proxy used after referent went away. ResourceWarning: Base class for warnings about resource usage. RuntimeError: Unspecified run-time error. RuntimeWarning: Base class for warnings about dubious runtime behavior. StopAsyncIteration: Signal the end from iterator.__anext__(). StopIteration: Signal the end from iterator.__next__(). SyntaxError: Invalid syntax. SyntaxWarning: Base class for warnings about dubious syntax. SystemError: Internal error in the Python interpreter. SystemExit: Request to exit from the interpreter. TabError: Improper mixture of spaces and tabs. TimeoutError: Timeout expired. TypeError: Inappropriate argument type. UnboundLocalError: Local name referenced but not bound to a value. UnicodeDecodeError: Unicode decoding error. UnicodeEncodeError: Unicode encoding error. UnicodeError: Unicode related error. UnicodeTranslateError: Unicode translation error. UnicodeWarning: Base class for warnings about Unicode related problems, mostly UserWarning: Base class for warnings generated by user code. ValueError: Inappropriate argument value (of correct type). Warning: Base class for warning categories. ZeroDivisionError: Second argument to a division or modulo operation was zero. __build_class__: __build_class__(func, name, /, *bases, [metaclass], **kwds) -> class __import__: __import__(name, globals=None, locals=None, fromlist=(), level=0) -> module __loader__: Meta path import for built-in modules. abs: Return the absolute value of the argument. all: Return True if bool(x) is True for all values x in the iterable. any: Return True if bool(x) is True for any x in the iterable. ascii: Return an ASCII-only representation of an object. bin: Return the binary representation of an integer. bool: bool(x) -> bool breakpoint: breakpoint(*args, **kws) bytearray: bytearray(iterable_of_ints) -> bytearray bytes: bytes(iterable_of_ints) -> bytes callable: Return whether the object is callable (i.e., some kind of function). chr: Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. classmethod: classmethod(function) -> method compile: Compile source into a code object that can be executed by exec() or eval(). complex: Create a complex number from a real part and an optional imaginary part. copyright: interactive prompt objects for printing the license text, a list of credits: interactive prompt objects for printing the license text, a list of delattr: Deletes the named attribute from the given object. dict: dict() -> new empty dictionary dir: dir([object]) -> list of strings divmod: Return the tuple (x//y, x%y). Invariant: div*y + mod == x. enumerate: Return an enumerate object. eval: Evaluate the given source in the context of globals and locals. exec: Execute the given source in the context of globals and locals. filter: filter(function or None, iterable) --> filter object float: Convert a string or number to a floating point number, if possible. format: Return value.__format__(format_spec) frozenset: frozenset() -> empty frozenset object getattr: getattr(object, name[, default]) -> value globals: Return the dictionary containing the current scope's global variables. hasattr: Return whether the object has an attribute with the given name. hash: Return the hash value for the given object. help: Define the builtin 'help'. hex: Return the hexadecimal representation of an integer. id: Return the identity of an object. input: Read a string from standard input. The trailing newline is stripped. int: int([x]) -> integer isinstance: Return whether an object is an instance of a class or of a subclass thereof. issubclass: Return whether 'cls' is a derived from another class or is the same class. iter: iter(iterable) -> iterator len: Return the number of items in a container. license: interactive prompt objects for printing the license text, a list of list: Built-in mutable sequence. locals: Return a dictionary containing the current scope's local variables. map: map(func, *iterables) --> map object max: max(iterable, *[, default=obj, key=func]) -> value memoryview: Create a new memoryview object which references the given object. min: min(iterable, *[, default=obj, key=func]) -> value next: next(iterator[, default]) object: The base class of the class hierarchy. oct: Return the octal representation of an integer. open: Open file and return a stream. Raise OSError upon failure. ord: Return the Unicode code point for a one-character string. pow: Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments print: print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) property: Property attribute. range: range(stop) -> range object repr: Return the canonical string representation of the object. reversed: Return a reverse iterator over the values of the given sequence. round: Round a number to a given precision in decimal digits. set: set() -> new empty set object setattr: Sets the named attribute on the given object to the specified value. slice: slice(stop) sorted: Return a new list containing all items from the iterable in ascending order. staticmethod: staticmethod(function) -> method str: str(object='') -> str sum: Return the sum of a 'start' value (default: 0) plus an iterable of numbers super: super() -> same as super(__class__, <first argument>) tuple: Built-in immutable sequence. type: type(object_or_name, bases, dict) vars: vars([object]) -> dictionary zip: zip(*iterables) --> A zip object yielding tuples until an input is exhausted.
一覧[編集]
abs[編集]
組込み関数 abs(x) は x の絶対値を返します[1]。
- 関数定義
def abs(n):
- 引数nの型による動作の違い
-
- 整数
- xが負の値なら -x を、そうでなければ x を返します。
- 浮動書数点数
- xが NaN なら NaN を、負の値なら -x を、そうでなければ x を返します。
- 複素数
- 実数部と虚数部の自乗和の平方根を返します。実数部・虚数部のいずれかが NaN の場合は NaN+NaNj を返します。
- メソッド __abs__ を持つクラスのインスタンス
- メソッド __abs__ を呼出しその値を返します。
- コード例
print(abs(12)) print(abs(-42)) print(abs(3.14)) print(abs(-2.73)) print(abs(+0.0)) print(abs(-0.0)) print(abs(2+2j)) print(abs(-3+-4j)) class AbsTest : def __init__(self, x) : self._x = x def __abs__(self) : return f"ABS({self._x})" x = AbsTest(-12) print(abs(x))
- 実行結果
12 42 3.14 2.73 0.0 0.0 2.8284271247461903 5.0 ABS(-12)
aiter[編集]
all[編集]
組込み関数 all(it) は、iterableオブジェクトitの要素がすべて真のときにTrueを返し、1つでも偽があればFalseを返します[2]。
- 関数定義
def all(it: Iterable) -> bool:
- コード例
# list print(type([])) print(all([True, True, True])) print(all([True, True, False])) print(all([])) # tuple print(type(())) print(all((True, True, True))) print(all((True, True, False))) print(all(())) # range print(range((0))) print(all(range(5))) print(all(range(5,2))) print(all(range(0))) # set print(type(set())) print(all({True, 1,"x"})) print(all({True, 1, "x", False})) print(all(set())) # dict print(type({})) print(all({1:True, 2:1, 3:"x"})) print(all({1:True, 2:1, 3:"x", 0:123})) print(all({})) # str print(type("")) print(all("abc")) print(all("True")) print(all("False")) print(all(""))
- 実行結果
<class 'list'> True False True <class 'tuple'> True False True range(0, 0) False True True <class 'set'> True False True <class 'dict'> True False True <class 'str'> True True True True
anext[編集]
any[編集]
組込み関数 any(it) は、iterableオブジェクトitの要素がすべて偽のときにFalseを返し、1つでも真があればTrueを返します[3]。
- 関数定義
def any(it: Iterable) -> bool:
- コード例
# list print(type([])) print(any([True, True, True])) print(any([True, True, False])) print(any([False, False, False])) print(any([])) # tuple print(type(())) print(any((True, True, True))) print(any((True, True, False))) print(any((False, False, False))) print(any(())) # range print(range((0))) print(any(range(5))) print(any(range(5,2))) print(any(range(0))) # set print(type(set())) print(any({True, 1,"x"})) print(any({True, 1, "x", False})) print(any({False, 0})) print(any(set())) # dict print(type({})) print(any({1:True, 2:1, 3:"x"})) print(any({1