Python/

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

Pythonは高水準の汎用プログラミング言語です。 Pythonの設計思想はコードの読みやすさに重点を置いています。 その構造に対するアプローチは独特であり、例えば、ブロックは波括弧 { } ではなくインデントで構造化されています。

また、Pythonはオブジェクト指向、インタプリタ、動的コーディング、クロスプラットフォームのプログラミング言語です。 これらのアプローチは、プログラマが小規模なプロジェクトから大規模なプロジェクトまで、自明で論理的なコードを書くことができるようにすることを目的としています。


基本事項[編集]

開発環境[編集]

「端末」を開いた場合のGNU/Linuxの画面 (Fedora 29)

Pythonは、UnixGNU/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の場合:

  1. 公式配布版Pythonインストーラ(英文)を使用し導入する。
  2. Microsoft Storeから Python を導入する。

の2通りの導入方法があります。

pythonの実行方法[編集]

Pythonの実行方法には、大きく分けて2つあります。

  1. インタラクティブモードでの実行方法
  2. ソースファイルを作成して実行する方法

インタラクティブモードでの実行方法[編集]

インタラクティブモード(REPL: Read-Eval-Print Loop)では、Pythonのコマンドを1行ずつ入力して実行することができます。

以下の手順で実行してください。

  1. ターミナルを開きます。
  2. "python"と入力します[1]
  3. ">>>"プロンプトが表示されますので、Pythonのコマンドを1行ずつ入力して実行します。

例えば、"print('Hello World')"と入力すると、"Hello World"と出力されます。

ソースファイルを作成して実行する方法[編集]

ソースファイルを作成する場合は、以下の手順で実行してください。

  1. テキストエディタを開きます。
  2. Pythonのプログラムを入力し、ファイル名を"*.py"で保存します(例:"hello.py")。
  3. ターミナルを開き、以下のコマンドを入力します[1]
    $ python ファイル名.py
    
  4. ソースファイルが実行されます。
    例えば、以下のような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
abが変数です。変数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]
  1. aに空の配列を代入
  2. aの値をprint ⇒ a= []
  3. bにaを代入
  4. aとbの値をprint ⇒ a= [] , b= []
  5. bの要素に100を追加
  6. 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
abcxyzが、変数です。

変数には意味のある名前をつけましょう[編集]

変数の名前には、そのプログラムの使い道にもとづいた名前をつけると、わかりやすくなります。

コード例
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]

識別子に使えるコード:

  • Lu - uppercase letters - 大文字
  • Ll - lowercase letters - 小文字
  • Lt - titlecase letters - 表題文字
  • Lm - modifier letters - 擬似文字
  • Lo - other letters - その他の文字(漢字はここ)
  • Nl - letter numbers - 数値を表す文字
  • Mn - nonspacing marks - 幅なし記号
  • Mc - spacing combining marks - 幅あり結合記号
  • Nd - decimal numbers - 十進数数字
  • Pc - connector punctuations - 連結句記号
  • Other_ID_Start - PropList.txt に明示的にリストされた文字
  • Other_ID_Continue - 同上

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]が混乱するので組込み関数や型と重複した識別子は使わないように心がけましょう。


参考文献[編集]


数値入力と文字入力と出力表示[編集]

入力[編集]

文字列の入力[編集]

文字列の入力には、組込み関数input()を使います。

x = input("文字を入力してみよう。")
print(2 * x)
文字を入力してみよう。
a
aa
たとえば a と入力すると、 aaが出力されます。
abcと入力すると、abcabc が出力されます。

なお、数字(12など)を入力しても、文字として認識されます。 たとえば上のプログラムの実行で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例外があがります。 例外を捕捉しないと、プログラムは異常終了してしまいます。

例外を捕捉し再入力を求める例
while True:
    try:
        s = input("数値を入力してください:")
        n = int(s)
        print(f"{n} の二倍は {2 * n} です。")
        break
    except EOFError as e:
        print(e)
        break
    except ValueError as e:
        print(e)


変数と文字列を同時に表示したい場合[編集]

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. ^ 1.0 1.1 1.2 Pythonのコマンド名は環境によって異なります。
  2. ^ リスト、タプル、辞書については後で取り扱います。
  3. ^ 3.10.0 Documentation » The Python Language Reference » 4. Execution model§4.2. Naming and binding” (2021年11月29日). 2021年11月30日閲覧。
  4. ^ C言語/C++/Javaの様な静的型付け言語では、変数は「値を入れる箱」で変数は名前と一対一なアドレスを持ちます(変数がレジスターに割付けられた場合は例外です。この場合も変数名(=識別子)とオブジェクトの間の一意性はあります)。
  5. ^ PEP 3131 -- Supporting Non-ASCII Identifiers” (2007年5月1日).テンプレート:Cite web/error
  6. ^ keyword — Testing for Python keywords” (2021年11月29日).テンプレート:Cite web/error
  7. ^ 3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3.1. Keywords” (2021年11月29日).テンプレート:Cite web/error
  8. ^ 3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3.2. Soft Keywords” (2021年11月29日).テンプレート:Cite web/error
  9. ^ Reserved classes of identifiersを「予約済み識別子クラス」と訳しました。ここで言うクラスはオブジェクト指向プログラミングでいう Class ではなう階級や種類という一般的普遍的な意味のクラスです。
  10. ^ 3.10.0 Documentation » The Python Language Reference » 2. Lexical analysis§2.3.3. Reserved classes of identifiers” (2021年11月29日).テンプレート:Cite web/error
  11. ^ 3.10.0 Documentation » The Python Language Reference » 6. Expressions§6.2. Atoms” (2021年11月29日).テンプレート:Cite web/error
  12. ^ 3.10.0 Documentation » The Python Language Reference » 6. Expressions§6.2.1. Identifiers (Names)” (2021年11月29日).テンプレート:Cite web/error
  13. ^ 将来のあなたかもしれません。
  14. ^ Lexical analysis # Formatted string literals” (2021年11月29日). 2021年11月29日閲覧。
  15. ^ JavaScriptのテンプレート・リテラルはヒアドキュメントの機能も持っています。
  16. ^ Python2.x系のサポートは2021/01/01に終了しました。 ⇒ PEP 373 -- Python 2.7 Release Schedule, PEP 404 -- Python 2.8 Un-release Schedule
  17. ^ 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 の例と同じ意味になります。
PerlRubyの後置のifと似ていますが else を伴うので、C言語系の条件演算子と(構文はまるで違いますが)機能的には同じです。
大概の場合、if文を使ったほうが読みやすいのですが、内包表記やラムダ式では式が要求されるので、if式を使う必要があります。
nanってナニ?
唐突に float("nan")、が出てきましたが、これがPythonでNaN(Not a Number; 非数)を得る方法で、他には math を import して math.nan を使う方法もあります。

nan は、浮動小数点演算の結果として、不正なオペランドを与えられたために生じた結果を表す値またはシンボルで[4]、NaNの体系的仕様は、無限大の表現などと共に1985年の IEEE 754 浮動小数点規格で標準が与えられています。

nanの特徴
どんな値と比較しても不一致
nan 自身とも一致しないです( nan == nan ⇒ False )
どんな数学関数の引数に与えても結果は nan
nan であるかは is 演算子をつかう( nan is nan ⇒ True)
あるいは math を import し math.isnan(x) をつかう( isnan(nan) ⇒ True)


論理演算子[編集]

「変数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 > 2 and x < 5

としていますが、これは

  • 2 < x < 5

と書くこともできます。両者は同じ意味になりますが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)

この例では、xyは最初の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という列挙型を定義し、REDGREENBLUEという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節は何に使うのでしょう?

1000以下の素数を求める(フラッグ版)
i = 2
while i <= 1000:
    j = 2
    is_prime = True
    while j * j <= i:
        if i % j == 0:
            is_prime = False
            break
        j += 1
    if is_prime:
        print(i, end=" ")
    i += 1
break で抜けたかをフラッグ is_prime で判断しています。
ゴチャゴチャしています。
1000以下の素数を求める(else版)
i = 2
while i <= 1000:
    j = 2
    while j * j <= i:
        if i % j == 0:
            break
        j += 1
    else:
        print(i, end=" ")
    i += 1
フラッグがなくなり簡素になりました。
1000以下の素数を求める(for+range版)
for i in range(2, 1000):
    for j in range(2, i):
        if i % j == 0:
            break
    else:
        print(i, end=" ")
こちらの方がより簡潔ですね。
while版と比べ内側のループが廻りすぎていますが(本来 sqrt(i)までで良い)、j2がなくなっているので1000までの区間なら性能劣化は軽微。
1000以下の素数を求める(素数集合更新版)
primes = []
for i in range(2, 1000):
    for prime in primes:
        if i % prime == 0:
            break
    else:
        primes.append(i)
        print(i, end=" ")
素数の集合を保持するリスト primes を導入しました
i の因数が primes になければ、iprimes に追加するロジックです
primes は素数が小さい順に保持されるので最も効率よく因数を探せます。

ループ完走の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文を持っていないので、大域脱出する場合は
  • ループ全体を関数にしてreturn文で脱出
  • tryをループをくくり例外をあげて脱出
  • プログラム自身を終了

などの工夫が必要です。

ここでは、ループと結合したelseを使った大域脱出を紹介します。

ループと結合したelseを使った大域脱出
for i in range(10):
    for j in range(10):
        for k in range(10):
            if (i == 2 and j == 3 and k == 5):
                break
            print(f"{i}{j}{k}", end=" ")
        else:
            print()
            continue
        break
    else:
        continue
    break
else:
    print("done!")
実行結果
000 001 002 003 004 005 006 007 008 009 
010 011 012 013 014 015 016 017 018 019 
020 021 022 023 024 025 026 027 028 029 
030 031 032 033 034 035 036 037 038 039 
040 041 042 043 044 045 046 047 048 049 
050 051 052 053 054 055 056 057 058 059 
060 061 062 063 064 065 066 067 068 069 
070 071 072 073 074 075 076 077 078 079 
080 081 082 083 084 085 086 087 088 089 
090 091 092 093 094 095 096 097 098 099 
100 101 102 103 104 105 106 107 108 109 
110 111 112 113 114 115 116 117 118 119 
120 121 122 123 124 125 126 127 128 129 
130 131 132 133 134 135 136 137 138 139 
140 141 142 143 144 145 146 147 148 149 
150 151 152 153 154 155 156 157 158 159 
160 161 162 163 164 165 166 167 168 169 
170 171 172 173 174 175 176 177 178 179 
180 181 182 183 184 185 186 187 188 189 
190 191 192 193 194 195 196 197 198 199 
200 201 202 203 204 205 206 207 208 209 
210 211 212 213 214 215 216 217 218 219 
220 221 222 223 224 225 226 227 228 229 
230 231 232 233 234
最外周のprint("done!")は(breakされた場合は)実行されません。


ループはスコープを作りません[編集]

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

脚註[編集]

  1. ^ 関数やメソッドの呼出しや復帰 return も制御構造と言えますが、本項では逐次・分岐・繰返しについて述べます。
  2. ^ 4.1. if Statements” (2021年11月17日). 2021年11月18日閲覧。
  3. ^ else節は、他の言語と違いfor文とも結合しますので注意してください。
  4. ^ ただし、Pythonでは math.asin(2) ↑ValueError であったりnanを返す前に例外が上がる事が多々あります。
  5. ^ 4.6. match Statements” (2021年11月17日). 2021年11月18日閲覧。
  6. ^ enum — Support for enumerations” (2021年11月17日). 2021年11月18日閲覧。
  7. ^ 少なくともFortranではdo文のループ変数に i が常用され、それ以前に数学でも数列の和など i が使用されます。由来は、iteration の i; integer の i など諸説あります。
  8. ^ 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
ifelse 条件演算子
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'>

脚註[編集]

  1. ^ sequenceと言う型があるわけではありません。
  2. ^ 辞書も3.6以降では順序固定ですが、シーケンスの一種だと考えることは稀です。

リストと文字列[編集]

リストの要素は、文字列だけ、あるいは数値だけでも、かまいません。

文字列だけのリストの場合、たとえば

コード例
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]

の構文で、この部分はどの言語でもほぼ同じですが、FortranBASICでは、

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つのメソッドはありません。

脚註[編集]

  1. ^ 3.10.1 Documentation » The Python Language Reference » 3. Data model ¶3.2. The standard type hierarchy” (2021年12月16日). 2021年12月16日閲覧。
  2. ^ falsy: 組込み関数bool() に与えると False を返すような式。False, None の他、空集合(set())、空文字列()、0、空タプル(tuple())、空リスト([])など
  3. ^ operator — Standard operators as functions — Python 3.10.1 documentation” (2021年12月15日). 2021年12月15日閲覧。
  4. ^ 標準モジュールの array あるいは、拡張モジュールの NumPy で連続した領域に要素が配置される配列が提供されますが、組込みオブジェクトの配列はありません。
  5. ^ 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'>

脚註[編集]

  1. ^ 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'>

脚註[編集]

  1. ^ 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'>

脚註[編集]

  1. ^ 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.

脚註[編集]

  1. ^ 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では、三角関数や指数関数なども、使えます。三角関数の単位は、ラジアンです。

※ ラジアンは弧度法の角度の単位で記号は rad です。とはなにか、高校で習います。度数法で円周は360°ですが、弧度法では2π rad です。
モジュール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_object1my_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_instanceMyClassのインスタンスであり、class_variableinstance_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を最初の引数として受け取り、その引数はメソッドが呼び出されたインスタンス自体を指します。このインスタンスを介して、メソッドはオブジェクトの状態を変更することができます。引数arg1arg2は、メソッドに渡され、メソッドの処理に使用されます。

上記のコードは、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.argcls.class_var を用いてメッセージを出力するという動作をします。

最後の行では、class_method をクラス名で呼び出しています。class_method がクラスメソッドであるため、第一引数にはクラスオブジェクト MyClass が自動的に渡されます。

スタティックメソッド[編集]

スタティックメソッドは、クラス自体やインスタンスから呼び出すことができます。スタティックメソッドは selfcls が必要ないため、第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 デコレータが使われています。このデコレータを使うことで、メソッドがスタティックメソッドであることを明示的に示すことができます。

スタティックメソッドはクラスに属していますが、インスタンスには属していないため、引数に selfcls を必要としません。そのため、スタティックメソッドは通常、インスタンス変数を使用する必要がない場合に使用されます。

上記の例では、@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__() メソッドを実装する必要があります。これらのメソッドを実装することで、クラスのインスタンスをイテレータとして扱うことができます。
  • __iter__() メソッドは、イテレータ自身を返す必要があります。通常は、クラスのインスタンス自身を返します。
  • __next__() メソッドは、次の要素を返します。もう要素がない場合は、StopIteration を発生させます。

以下は、クラスのインスタンスに for 文を適用する例です。

class MyIterator:
    def __init__(self, items):
        self.items = items
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current < len(self.items):
            item = self.items[self.current]
            self.current += 1
            return item
        else:
            raise StopIteration

my_iter = MyIterator([2, 3, 5])

for item in my_iter:
    print(item)
# 2
# 3
# 5

上記の例では、MyIterator というクラスを定義し、__iter__()__next__() メソッドを実装しています。 MyIterator クラスのインスタンスを for 文でループさせることができます。


継承[編集]

継承とは、既存のクラスを基に新しいクラスを作り出すことで、既存のクラスの機能を引き継ぎながら、新たな機能を追加することができます。

スーパークラスの定義[編集]

スーパークラスは、継承元のクラスのことを指します。スーパークラスの定義は、通常のクラス定義と同じように行います。

以下の例では、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 は、nameage の属性を持ち、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の標準モジュールの中で、継承を想定して設計されたクラスとしては、以下のようなものがあります。
  1. collections.abc モジュール
    • Iterable: イテレーション可能なオブジェクトを定義する抽象基底クラス
    • Container: 要素の有無を調べることができるオブジェクトを定義する抽象基底クラス
    • Sized: 要素の数を返す len() 関数を実装することができるオブジェクトを定義する抽象基底クラス
    • Callable: 呼び出し可能オブジェクトを定義する抽象基底クラス
    • Hashable: ハッシュ可能なオブジェクトを定義する抽象基底クラス
    • Mapping: キーと値の対応を表す辞書型オブジェクトを定義する抽象基底クラス
    • MutableMapping: キーと値の対応を表す辞書型オブジェクトを変更することができる抽象基底クラス
    • Sequence: インデックスを用いて要素にアクセスできるオブジェクトを定義する抽象基底クラス
    • MutableSequence: インデックスを用いて要素にアクセスし、変更することができるオブジェクトを定義する抽象基底クラス
  2. enum モジュール
    • Enum: 列挙型オブジェクトを定義する基底クラス
  3. abc モジュール
    • ABC: 抽象基底クラスを定義する基底クラス
    • abstractmethod: 抽象メソッドを定義するためのデコレータ
  4. typing モジュール
    • Type: クラスオブジェクトを表す型を定義するクラス
    • TypeVar: 型変数を定義するクラス
    • Generic: ジェネリッククラスを定義する基底クラス
    • Protocol: プロトコルを定義する基底クラス

これらのクラスは、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

このように定義することで、インスタンスから以下のようにして nameage にアクセスすることができます。

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

このように定義することで、インスタンスから以下のようにして nameage にアクセスし、変更することができます。

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では、型アノテーションを使用して関数やメソッドの引数や返り値の型を指定できますが、クラスの属性やメソッドの戻り値などでも型アノテーションを指定することができます。

例えば、以下のようにクラス定義時に属性に対して型アノテーションを指定することができます。

class MyClass:
    def __init__(self, value: int) -> None:
        self.value = value

    def add_value(self, x: int) -> int:
        return self.value + x

この例では、__init__メソッドの引数valueと、add_valueメソッドの引数x、そしてadd_valueメソッドの戻り値に対して、型アノテーションが指定されています。value属性は整数型を持ち、add_valueメソッドは整数型の引数を受け取り、整数型の戻り値を返すことを表しています。

また、クラス全体に対して型アノテーションを指定することもできます。例えば、以下のようにクラス定義の先頭で型アノテーションを指定することができます。

class MyClass:
    value: int

    def __init__(self, value: int) -> None:
        self.value = value

    def add_value(self, x: int) -> int:
        return self.value + x

この例では、クラス定義の先頭でvalue属性に対して整数型を指定しています。このように、クラス定義の先頭で型アノテーションを指定することで、クラス全体に対して型を指定することができます。

なお、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が使用されます。

脚註[編集]

  1. ^ 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__属性を使って型チェックを行うためには、外部ライブラリを使用する必要があります。

参考文献[編集]

ファイルへの書込み[編集]

ファイルを書くにも読むにも、まず、そのファイルを開く必要があります。 ファイルを開くには、組込み関数 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