Python基本文法まとめ


Hello World  Hello World
書式  改行
   インデント
   コメント
リテラル  数値のリテラル
   浮動小数点のリテラル
   文字列のリテラル
   文字列の連結解釈 "ABC"'DEF'
   文字列の途中で行を折り返す "UVW\ 
   エスケープシーケンス \t \n
   バイト列のリテラル b'\x00\x02\x1a'
   ブール値のリテラル True, False
   None None
変数  変数の代入 a = 10
   変数の削除 del var
演算  算術演算 * / + -
   浮動小数点値の丸め round()
   代入演算 +=, *=
   ビット演算(論理演算) a & b
   ビットシフト a << 16
   文字列・バイト列の連結演算 "AB"+'CD'
   等価演算・比較演算 a != 20
   オブジェクトの等価演算 a is not b
   真偽の論理演算 a>10 or a<5
   演算の優先
   データ型取得・データ型比較 type()
データ変換  暗黙の数値間変換
   数値の明示的型変換(キャスト) float('3.5')
   文字列への変換 str(123)
   バイト列と数値の変換 to_bytes(), from_bytes()
   文字列とバイト列の変換 encode(), decode()
文字列メソッド  文字列を区切り文字で分割 split()
   文字列を中央・左寄せ・右寄せ center()
   文字列を大文字・小文字変換 upper(), lower()
   文字列の前後の文字を除去 strip()
   文字の種類を判定 isalpha(), isdigit()
文字列検索  文字の一致検索 find()
   文字の先頭と末尾の部分一致 startswith(), endswith()
文字列置換  文字列を別の文字列に置換 replace()
   文字列のフォーマット format(), f"{a}" 
バイト列  バイト列の生成 bytes()
   変更可能なバイト列の生成 bytearray()
リスト  リストの生成 list(), ["A","B"]
   配列からのリストの生成
   リストのアンパック a,n = [10,20]
   リストの連結 ["A","B"] + [10,20]
   リストの拡張 lst.extend()
   リストへ要素を追加 lst.append()
   リストへ要素を挿入 lst.insert()
   リストから要素を削除 lst.remove()
   リストから要素の取り出し lst.pop()
   リストから要素を検索 lst.index()
   リストから要素の数を取得 lst.count()
タプル  タプルの生成 tuple(), ("A","B")
   配列からのタプルの生成
   タプルのアンパック a,n = (10,20)
   タプルの連結 ("A","B") + (10,20)
   タプルから要素を検索 tp.index()
   タプルから要素の数を取得 tp.count()
辞書  辞書の生成 dict(), {"A": 10}
   リスト・タプルからの辞書の生成
   キーを辞書に追加する dic["A"] = 30
   辞書から要素を削除 del dic["A"]
   辞書の拡張 dic.update()
セット(集合)  セットの生成 set()
   配列からのセットの生成
   セットへ要素を追加 se.add()
   セットから要素を削除 se.remove()
   セットの集合演算 s1&s2, s1|s2
配列オブジェクト共通  添字による配列の参照 arr[4]
   スライス arr[2:6:-1]
   文字列・バイト列・コレクションの長さ len()
   コレクションのクリア col.clear()
   コレクションのコピー col.copy()
   コレクションの要素存在チェック in
イテレーション  配列のイテレーション for n in arr:
   辞書のイテレーション for k in dic:
   順序を変えてイテレーション sorted(), reversed()
   整数範囲のイテレーション range()
   イテレータで繰り返し参照 iter(), next()
条件による実行制御  条件の評価で分岐 if A:
   三項演算 A if B else C
   条件がTrueの間繰り返す while A:
   繰り返しの強制終了 breaj
   繰り返しの継続 continue
   条件の評価演算
内包表記  内包表記 [C for A in B]
なにもしない処理  なにもしない処理 pass
関数  関数定義 def func():
   関数呼び出し func(arg)
   戻り値のアンパック a,b = func()
   デフォルト引数 def func(a=10)
   キーワード引数 func(3, b=5)
   引数のタプル参照 func(*args)
   引数の辞書参照 func(**kwargs)
   関数オブジェクト f = func
   ラムダ式(無名関数) lambda x:x*10
   関数の関数内定義
   関数と変数のスコープ
   関数内のグローバル変数の変更 global gv
例外処理  例外の捕捉 try: except:
   指定の例外を捕捉 except Exception as e:
ライブラリの利用  ライブラリをインポート import mod
   モジュール名の省略 from mod import *
   モジュール名の別名 import mod as alias
コマンドライン引数  コマンドライン引数の参照 sys.argv[]

Hello World

Hello World

print("Hello World")

書式

改行

一行に文を複数含める場合は「;」で区切る a = 10 + x; b = 100
行末に「\」を置いて文を折り返すことができる s = "あいうえおかきくけこ" \
    + "さしすせそ"
x = a + b * c - d * \
    e + f
「()、[]、{}」の中は自由に折り返すことができる s = ("あいうえおかきくけこ"
    + "さしすせそ")
x = (a + b * c - d *
    e + f)
インタプリタは改行を以って入力された行の解釈を行います。

インデント

if a > 100:
    print(a)        # ブロック開始
    b = a * 10
    print(b)        # ブロック終わり
制御構文、関数定義、クラス定義に伴うブロックは、行のインデントの深さで認識されます。同じブロックが継続している区間は、行頭のインデントがそろっていなければなりません。
インデントは空白4文字が基本とされていますが、インデントの頭がそろっていれば2文字でもタブ文字でもかまいません。

コメント

a = 10  # aに10を代入した
# print(a)

'''
複数行文字列をコメントのように使う
a = 10
print(a)
'''
「#」以降をインタプリタは解釈しないのでコメントとして使えます。
複数行を囲むようなコメントの方法はありませんが、代入のない複数行文字列をコメントのように使う方法があります。

リテラル

数値のリテラル

10進数 先頭が0でない数値 12340
2進数 0bからはじまる0か1の数値 0b1011
8進数 0oからはじまる0~7の数値 0o467
16進数 0xからはじまる0~9、A~Fの数値 0x3f9A
10進数の整数は先頭を0にはできません。「05」は5とは解釈されずエラーになります。
16進数の10~15に相当するA~Fは小文字でもかまいません。
整数の値の範囲は、Python2まではシステムアーキテクチャに準じた32ビットや64ビットの範囲とされていましたが、Python3からは無制限となりました。次の計算は、オーバーフローにならずに問題なく結果が得られます。
>>> print(123456789**10)
822526259147102579504761143661535547764137892295514168093701699676416207799736601

浮動小数点のリテラル

小数点を含む数値 3.1416
仮数部と指数部で表記 0.031416e+2= 0.031416 ×102
314.16e-2= 314.16 ×10-2
浮動小数点値は、倍精度実数である64ビットの範囲で扱われます。表現可能な仮数は64ビットで表現可能な範囲に制限されます。32ビットの単精度実数はありません。
2.2250738585072014e-308~1.7976931348623157e+308

文字列のリテラル

クォーテーションで囲む間を文字列のリテラルを解釈されます。
"〜" または'〜'
'ABC'、"あいう" 文字列
"''"、 '""' ダブル/シングルクォーテーションは互いを文字列として解釈する
''、 "" 空文字列
'''UVW
XYZ'''
"""OPQ
RST
UVW"""
複数行の文字列
3つクォーテーションを連続させた区間は、改行を含めることができる
文字列内部で処理される文字列データはUnicodeで扱われます。

文字列の連結解釈

print("ABC"
'DEF')
ABCDEF
文字列リテラルを、"AAA""BBB"のように連続させると、インタプリタは"AAABBB"のように一つの文字列として結合して解釈します。

文字列の途中で行を折り返す

print("UVW\
XYZ")
UVWXYZ
文字列の行末に「\(バックスラッシュ)」を置いて、次の行から文字列の続きを書くことができます。「\」自身は文字列には含まれません。

エスケープシーケンス

print('ABC\nDEF')
print('GHI\tJKL')
print('ABC\'DEF')
print("\x3f")
print("\u3042")
ABC
DEF
GHI     JKL
ABC'DEF
?

改行やタブ文字のような制御文字を、「\(バックスラッシュ)」に続く1文字との組み合わせによるエスケープシーケンスで表します。
エスケープ文字  
\a ベル
\b バックスペース
\t タブ
\n 改行
\r 復帰(行頭へ移動)
\' '(シングルクォーテーション)
\" "(ダブルクォーテーション)
\\ \(エスケープ文字そのもの)
\035 3桁の0-7の数値からなる8進数が示すコードの文字
\xEB 2桁の0-9A-Fの数値からなる16進数が示すコードの文字
\u1340、\U0001f300 u+4桁またはU+8桁の16進数からなるUnicode文字

バイト列のリテラル

b'\x00\x02\x1a'、b"\xa8\x90\x03" バイト列
b"\x00\x02\t\n\x0c\xff" 16進数以外のエスケープ文字でもよい
b"abcd$%!\x00" ASCII文字は直接表記できる
先頭に「b」を置いたクォーテーションで囲った区間はバイト列のリテラルとして解釈されます。
b'〜' または、b"〜"
1バイト毎のデータはエスケープ文字か、表示可能なASCII文字で表記します。

ブール値のリテラル

True
False
ブール値(真理値)のリテラルは「True」と「False」であり、つづりはこの通りでなければならず、TRUEやfalseのようにはできません。

None

a = None
Noneは「値が無い」ことを表す特殊なデータ型です。変数にNoneを代入することで、「変数は存在するが値が未定」な状態にできます。

変数

変数の代入

a = 10          # 代入と同時に変数が作られる
a = "ABC"       # 別のものを代入して上書き
b = [1, 2]
変数名 = オブジェクト 
変数宣言はありません。変数のデータ型は代入するもので決定します。新しい変数名へデータの代入が行われた時点でその変数が新たに作られ、代入した値で初期化されます。
変数の使用可能文字
英字
数字(ただし先頭文字にはできない)
アンダーバー(アンダースコア)

変数の削除

a = 100
del a
print(a)
NameError: name 'a' is not defined
変数はdel文により削除できます。削除した変数は未定義となります。

演算

算術演算

a = 7 + 3.2     # 10.2
a = 6.5 - 12    # -5.5
a = -33 + +1    # -32
a = 3 * 1.6     # 4.800000000000001
a = 10 / 3      # 3.3333333333333335
a = 10 // 3     # 3
a = 10 % 3      # 1
a = 2 ** 4      # 16
数値データの算術演算子は以下があります。
演算子   演算
+ - 加算・減算(及び各単項演算)
* / 乗算・除算
// 切り捨て除算
% 剰余(モジュロ)
** べき乗
0での徐算はできません。エラーとなり例外が発生します。
x = 10 / 0
ZeroDivisionError: division by zero

浮動小数点値の丸め

print(round(2.3456, 2))     # 2.35  
print(round(2.3456))        # 2 
round()関数により浮動小数点値を指定桁で四捨五入できます。桁を省略した場合は整数値に丸められます。
round(浮動小数点, [桁])

代入演算

a = 10
a += 1
a *= 3
変数の演算とその変数自身への代入は代入演算子でまとめることができます。
例えば「a=a+n」は「a+=n」のようにできます。
  += -= *= /=
代入演算子の種類 **= //= %= &=
  |= ^= <<= >>=

ビット演算(論理演算)

a = 0b0101
b = 0b1001
x = a & b       # 1
x = a | b       # 1101
x = a ^ b       # 1100
x = ~a          # 1010 = -110 = -6
数値データのビット演算子(論理演算子)は以下があります。
演算子   演算
& 論理積(AND)
| 論理和(OR)
^ 排他的論理和(XOR)
~ 否定(NOT)
否定(not)は2の補数になります。
~x ⇒  -(x + 1)

ビットシフト

a = 0b0101
x = a >> 1      # 0b10
x = a << 1      # 0b1010
b = 0b1010
x = b >> 1      # 0b101
x = b << 1      # 0b10100
x = b << 16     # 0b10100000000000000000
シフト演算子は数値を2進数としたとき、シフト演算子に続く値のビット数だけ左右にシフトします。
シフト後の最上位または最下位のビットには0が追加されます。左シフトでは最上位ビットは消えることなく右に0ビットが付け足されます。
>> n nビットシフト
<< n nビットシフト

文字列・バイト列の連結演算

s = "AB" + 'CD'
print(s)        # ABCD
s += "EF"
print(s)        # ABCDEF
s = "XYZ"
print(s * 3)    # XYZXYZXYZ

b1 = b"\x01\x02" 
b2 = b"\x03\x04" 
print(b1 + b2)  # b'\x01\x02\x03\x04'
print(b1 * 3)   # b'\x01\x02\x01\x02\x01\x02'
文字列またはバイト列は「+」で連結した文字列/バイト列を作成できます。
「*」で乗算すると、その倍数を繰り返す文字列/バイト列が作成されます。
s1 + s2    s1とs2を連結
s * j      sをj回繰り返す

等価演算・比較演算

a = 10
print(a == 10)  # True
print(a != 20)  # True
print(a > 5)    # True
print(a >= 10)  # True
print(a < 20)   # True
print(a <= 10)  # True
数値の等価、大小を等価演算・比較演算で評価し、結果をブール値で返します。
A==B AとBの値が等しい
A!=B AとBの値が等しくない
A>B、A<B AがBより値が大きい/小さい
A>=B、A<=B AとBの値が等しい、またはAがBより値が大きい/小さい
等価演算は文字列・バイト列・コレクション型の内容が同一かどうかを調べることができます。
集合の比較では、順不同に同じ要素が存在すれば一致と判断されます。
辞書の場合は、キーか値のどちらかが異なれば、不一致と判断されます。
s = "ABC"
print(s == "ABC")   # True
print(s != "DEF")   # True

b1 = b"/x01/x02/x03/x04" 
b2 = b"/x01/x02/x03/x04" 
print(b1 == b2)             # True
b3 = b"/x01/x22/x03/x04" 
print(b1 == b3)             # False

tp = (10, 20)
print(tp == (10, 20))       # True
lst = [10, 20]
print(lst == [10, 20])      # True
se = {10, 20}
print(se == {20, 10})       # True
dic = {"a": 10, "b": 20}
print(dic == {"a": 10, "b": 20})    # True
print(dic == {"a": 10, "c": 20})    # False
print(dic == {"a": 10, "b": 30})    # False

オブジェクトの等価演算 is/is not

a = [1, 2, 3]
b = a
print(a is b)       # True
print(a is not b)   # False
c = a.copy()
print(a == c)       # True
print(a is c)       # False
x = None
print(x is None)    # True
値ではなく、オブジェクトの参照元が同じかどうかをis、is not演算子で評価し、ブール値で返します。
コピーを代入した変数とコピー元との間では、「==」で比較すると値が一致するのでTrueですが、isの評価では、コピーにより互いに別々のオブジェクトを持つためFalseになります。
Noneは常に唯一のNoneオブジェクトを参照するので、isの評価は常にTrueです。

真偽の論理演算

a = 3
b = 8
print(a > 10 or a < 5)      # True
print(a < 10 and b >= 5)    # True
a = None
print(not a)                # True
関係演算での評価や式の評価結果を、論理演算で評価し、ブール値で返します。
A and B AかつB(AND)
A or B AまたはB(OR)
not A Aでない(NOT)

演算の優先

演算子の優先順位は優先度が高い順に次のようになっています。同列内では左がより高い優先です。
最も高い ** べき乗
~ 否定(補数)
-a, +a 単項演算
%, *, /, // 剰余、乗算、除算、切り捨て除算
+, - 加算、減算
<<, >> ビットシフト
&, ^, | ビット論理積、排他的論理和、論理和
>, >=, <, <= 比較演算
==, != 等価演算
in, not in 所属、非所属
is, is not オブジェクトの同一、非同一
not 論理否定
and, or 論理積、論理和
最も低い lambda ラムダ
数学と同様に( )で囲んだ中の式が演算子の優先順位に関係なく先に演算されます。また( )が式に複数ある場合は、左の項から演算されます。
a = 4 
b = (a + 2) * 10
print(b)

if (a > 3) and (b > 30):
    print(a)
60
4

データ型取得・データ型比較

a = 10
print(type(a))      # <class 'int'>
a = "ABC"
print(type(a))      # <class 'str'>
a = [1, 2]
print(type(a))      # <class 'list'>
def Fun():
    pass
print(type(Fun))    # <class 'function'>
全てのデータは内部的に各データ型のクラスで定義されています。
type()関数にデータを与えると、そのデータ型(クラス)が取得できます。
データ型 = type(オブジェクト)
主なプリミティブなデータ型名(クラス名)は以下のものがあります。
int(整数) float(浮動小数点) str(文字列)
bool(ブール) list(リスト) tuple(タプル)
dict(辞書) tuple(タプル) set(セット)
function(関数)
データ型の判定
a = 100
print(type(a) is int)       # True
a = "ABC"
print(type(a) is str)       # True
print(type(a) is not float) # True
print(type(a) == str)       # True
type()で取得したデータ型を「is(not is)」、あるいは比較演算子で一致(不一致)判定ができます。
type(オブジェクト) is データ型名
type(オブジェクト) not is データ型名
type(オブジェクト) == データ型名
type(オブジェクト) != データ型名

データ変換

暗黙の数値間変換

a = 4 * 2.4             # 9.6
a = True + 2            # 3
a = 5.0 - False         # 5.0
異なる数値型の演算では、自動的(暗黙)に適切なデータ型の変換が行われます。
整数と浮動小数点が同じ式に混在する場合は、整数は自動的に浮動小数点に変換してから演算されます。
4 * 2.4         4を4.0に変換してから演算
ブール値が数値と共に演算する場合は、Trueは1、Falseは0になります。
True + 2        Trueが1に変換

5.0 - False     Falseが0.0に変換

数値の明示的型変換(キャスト)

a = int(12.3)           # 12
a = int(1.72e2)         # 172
a = int('456')          # 456
a = int(True)           # 1
a = int(False)          # 0

a = float(12)           # 12.0
a = float('34.5')       # 34.5
a = float('2.5e3')      # 2500.0
a = float(True)         # 1.0
a = float(False)        # 0.0

a = int('2.34e3')       # エラー
a = int('0xba')         # エラー
データ型(x)のようにすると、xのそのデータ型(クラス)への変換を試みます。
例えばint(x)は、xを可能な限り整数に変換して返します。変換できないオブジェクトが指定された場合はエラー(ValueError例外)となります。
データ型(x)       データ型への変換

文字列への変換

print(str(123))         # 123
print(str(34.5))        # 34.5
print(str(True))        # True
print(str(False))       # False
print(str([77, 88]))    # [77, 88]
print(str(None))        # None
str(x)は、xの文字列への変換を可能な限り試みます。
リストなどのコレクションも含めて、あらゆるオブジェクトの文字列変換を試みます。

バイト列と数値の変換

n = 32767
print(n.to_bytes(2, "big"))     # b'\x7f\xff'
print(n.to_bytes(2, "little"))  # b'\xff\x7f'
print(n.to_bytes(4, "little"))  # b'\xff\x7f\x00\x00'

a = int.from_bytes(b"\x7f\xff", "big")      # a = 32767
a = int.from_bytes(b"\xff\x7f", "little")   # a = 32767
整数値は次のようにバイト列へ変換、あるいはバイト列から整数へ変換できます。
バイトオーダーには、ビッグエンディアンは「big」、リトルエンディアンは「little」を指定します。
バイト列 = 整数.to_bytes(バイト数, バイトオーダー)
整数値 = int.from_bytes(バイト列, バイトオーダー)

文字列とバイト列の変換

s = "あいう"
print(s.encode())           # b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
print(s.encode("utf-8"))    # b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
print(s.encode("cp932"))    # b'\x82\xa0\x82\xa2\x82\xa4'
s = "ABCD\a"
print(s.encode("ascii"))    # b'ABCD\x07'

bi = b"\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86"
print(bi.decode())          # あいう
bi = b"\x31\x32\x33"
print(bi.decode("ascii"))   # 123
print(str(bi, "utf-8"))     # あいう

print(b"\xa1\xa2\xa3\xaf".hex())    # a1a2a3af
文字列は、encode()メソッドにより任意の文字コードのバイト列に変換できます。
文字コードを省略した場合は、デフォルトとしてUTF-8が適用されます。
バイト列 = 文字列.encode(文字コード)
バイト列は、decode()メソッドにより文字列に変換できます。
指定する文字コードで文字列を解釈します。省略時はUTF-8が適用されます。
文字列 = バイト列.decode(文字コード)
あるいはstr()にバイト列と文字コードを指定すると、バイト列を文字列に変換できます。
文字列 = str(バイト列, 文字コード)
バイト列は、hex()メソッドにより16進数を表す文字列に変換できます。1バイトを2桁の16進数で表現します。
16進数の文字列 = バイト列.hex()

文字列メソッド

文字列を区切り文字で分割

s = "ABC DEF GHI"
sl = s.split()          # ['ABC', 'DEF', 'GHI']
s = "ABC/DEF/GHI"
sl = s.split('/')       # ['ABC', 'DEF', 'GHI']
s = "A B C,D E F,G H I"
sl = s.split(',')       # ['A B C', 'D E F', 'G H I']

s = "ABC\nDEF\nGHI"
sl = s.splitlines()     # ['ABC', 'DEF', 'GHI']
文字列には、文字列を加工するメソッドが用意されてます。
split()メソッドは、文字列を指定する区切り文字で分割してリストを返します。
区切り文字を省略すると、デフォルトで空白文字が適用されます。
リスト = 文字列.split(区切り文字)
またsplitlines()メソッドは、改行文字を含む文字列を、行ごとに区切ってリストにします。
リスト = 文字列.splitlines()

文字列を中央・左寄せ・右寄せ

w = "ABC"
print(f"[{w.center(7)}]")   # [  ABC  ]
print(f"[{w.ljust(7)}]")    # [ABC    ]
print(f"[{w.rjust(7)}]")    # [    ABC]
center()、ljust()、rjust()メソッドは半角桁数幅のスペースの中に、文字列をセンタリング・左寄せ・右寄せに配置した文字列を返します。
文字列.center(半角桁数) センタリング
文字列.ljust(半角桁数) 左寄せ
文字列.rjust(半角桁数) 右寄せ

文字列を大文字・小文字変換

s = "abcDEF"
print(s.upper())            # ABCDEF
print(s.lower())            # abcdef
print(s.swapcase())         # ABCdef
upper()、lower()、swapcase()メソッドは、英字の大文字と小文字を変換します。
文字列.upper() 大文字に変換
文字列.lower() 小文字に変換
文字列.swapcase() 大文字と小文字を交換

文字列の前後の文字を除去

s = "  ABC  "
print(f"[{s.strip()}]")     # [ABC]
print(f"[{s.lstrip()}]")    # [ABC  ]
print(f"[{s.rstrip()}]")    # [  ABC]
s = "123ABC456"
print(f"[{s.strip('123456')}]") # [ABC]
strip()メソッドは、引数に指定する文字列に含まれる文字を、文字列の先頭と末尾から除去します。
引数を省略するとデフォルトで空白・タブが除去されます。また、lstrip()は先頭のみ、rstrip()はメソッド末尾のみを除去します。
文字列.strip(除去文字からなる文字列) 先頭と末尾から文字を除去する
文字列.lstrip(除去文字からなる文字列) 先頭の文字を除去する
文字列.rstrip(除去文字からなる文字列) 末尾の文字を除去する

文字の種類を判定

print("XyZ".isalpha())          # True
print("12AB".isalnum())         # True
print("ABC".isupper())          # True
print("abc".islower())          # True
print("123".isdigit())          # True
print("\t \n".isspace())        # True
print("abcあいう".isascii())    # False
is〜から始まるメソッドにより、文字列に含まれる文字の種類を判定します。
isalpha() 文字列がすべて英字ならTrue
isalnum() 文字列がすべて英数字ならTrue
isupper() 文字列がすべて大文字ならTrue
islower() 文字列がすべて小文字ならTrue
isdigit() 文字列がすべて数字ならTrue
isspace() 文字列がすべて改行か空白ならTrue
isascii() 文字列がすべて半角文字(ASCII文字)ならTrue

文字列検索

文字の一致検索

s = "ABCDEFGABCDEFG"
i = s.find("DEF")       # 3
i = s.rfind("BCD")      # 8
c = s.count("DEF")      # 2
文字列のfind()メソッドは、文字列の中から指定の文字列パターンに最初に一致した位置(先頭は0)を返します。
rfind()メソッドは文字列の後方から検索して最初に一致した位置を返します。
count()メソッドは、文字列パターンが一致した回数を返します。
最初に一致した位置 = 文字列.find(文字列パターン)
後ろから一致した位置 = 文字列.rfind(文字列パターン)
パターン一致した回数 = 文字列.count(文字列パターン)

文字の先頭と末尾の部分一致

s = "ABCDEFG"
s.startswith("ABC")         # True
s.startswith("ABC", 0, 5)   # True
s.startswith("ABC", 0, 2)   # False
s.startswith("BCD", 1)      # True

s.endswith("EFG")           # True
s.endswith("EFG", 4, 7)     # True
s.endswith("EFG", 4, 6)     # False
s.endswith("FG", 5)         # True
文字列のstartswith()メソッドは文字列の先頭から、endswith()メソッドは末尾からの部分一致を調べます。
文字列中の一致を調べる範囲を引数で指定できます。一致範囲は、開始で指定する位置から停止で指定する位置のひとつ手前までになります。例えば開始を0、停止を3に指定した場合は、一致を調べる範囲は0〜2となります。開始と停止を省略した場合は、それぞれ文字列の先頭と末尾位置が適用されます。
True|False = 文字列.startswith(文字列パターン, 開始, 停止)
True|False = 文字列.endswith(文字列パターン, 開始, 停止)

文字列置換

文字列を別の文字列に置換

s = "ABCDEFGABCDEFG"
r = s.replace("DEF", "(DEF)")       # ABC(DEF)GABC(DEF)G
r = s.replace("DEF", "(DEF)", 1)    # ABC(DEF)GABCDEFG
文字列のreplace()メソッドは、文字列中の文字列パターンに一致する箇所を、指定する文字列に置き換えます。
先頭からの置換する回数を指定できます。置換後の文字列を新たに生成して返します。元の文字列は変更しません。
置換後文字列 = 文字列.replace(文字列パターン, 置換文字列, 回数)

文字列のフォーマット

print("s={} i={} f={}".format("ABC", 100, 1.23))
# s=ABC i=100 f=1.23

a = 100
b = "ABC"
c = 1.23
print("s={1} i={0} s={1} f={2:.3f}".format(a, b, c))
# s=ABC i=100 s=ABC f=1.230

print(f"s={b} i={a} f={c:.3f}")
# s=ABC i=100 f=1.230
文字列のformat()メソッドは、文字列中の{}の部分に、format()に与える引数を対応させて出力できます。{}には書式を指定できます。
{n}         format()の引数の位置を指定 先頭は0とします。
{n:書式}    「:」に続き表示の書式を指定
あるいはformat()メソッドを使わずに、文字列リテラルの前に「f」をつけた f"~"、f'~'の中に{変数}のように直接表示したいデータを埋め込む方法があります。
f"... {変数} ..."
f'... {変数:書式} ...'
書式の指定方法は以下の通りです。
{:8} 255      8桁で左寄せ
{:<8} ABC      8桁で左寄せ
{:^8}   255    8桁で中央せ
{:>8}      ABC 8桁で右寄せ
{:08} 00000255 8桁で0で埋める
{:b} 11111111 2進数
{:o} 377 8進数
{:x} ff 16進数
{:.2} 0.12 小数点以下2桁
{:.6f} 0.123400 小数点以下6桁
{:.6e} 1.2340e-01 浮動小数点を指数で表記
{:.0%} 12% パーセントで表記

バイト列

バイト列の生成

print(bytes(5))             # b'\x00\x00\x00\x00\x00'
print([1, 8, 15, 128, 23])  # b'\x01\x08\x0f\x80\x17'
print(bytes(range(1, 5)))   # b'\x01\x02\x03\x04'
バイト列は1バイト単位でバイナリデータを格納する配列データです。
byte()に整数値を与えると、その数の0からなるバイト列が生成されます。1バイト整数値からなるリスト、タプルを指定すると、数値の列からなるバイト列が生成されます。また、range()が返す反復可能(イテラブル)な配列を指定すると、その数値列からなるバイト列が生成されます。
バイト列 = bytes(整数値)
バイト列 = bytes(数値リスト)

変更可能なバイト列の生成

lst = [1, 2, 3, 4, 5]
barr = bytearray(lst)
barr[ 2 ] = 0xbb
print(barr)         # bytearray(b'\x01\x02\xbb\x04\x05')
byte()が生成するバイト列は変更できません。それに対し、bytearray()は変更可能なバイト列を生成します。
ただし、bytearray()で生成したバイト列はbytearrayクラスのオブジェクトであり、byte()で生成されるバイト列とは異なります。

リスト

リストの生成

lst = []                    # 空のリスト
lst = list()                # 空のリスト
lst = [10, 20, 30, 40]
lst = ["AB", "CD", "EF"]
lst = [10, "AB", 20, "CD"]  # 異なるデータ型のリスト
lst = [a, 200, b, 400]      # 変数のリスト
リストは、複数のオブジェクトを順序付けて格納するコレクションです。リストは要素の追加・削除など変更が可能です。
リストは、[]の中に要素をカンマ「,」で区切って並べます。
[要素, 要素, ...]
リテラルのみならず、変数や演算式、関数、リストやタプルなどのコレクションを要素にできます。

配列からのリストの生成

lst = list("ABC")                   # 文字列から
print(lst)                          # ['A', 'B', 'C']
lst = list(b"\x01\x02")             # バイト列から
print(lst)                          # [1, 2] 
lst = list("ABC", 123, "DEF")       # タプルから
print(lst)                          # ['ABC', 123, 'DEF']
lst = list({1:"A", 2:"B"})          # 辞書から
print(lst)                          # [1, 2]
lst = list({"A", "B"})              # セットから
print(lst)                          # ['A', 'B']
lst = list(range(1, 3))             # range()から
print(lst)                          # [1, 2]
list(x)は、xのリストへの変換を試みます。反復可能(イテラブル)な配列型のオブジェクトはリストに変換できます。
リスト = list(配列オブジェクト)
文字列・バイト列は、1文字・1バイトのリストになります。辞書からの場合は、キーのみからなるリストになります。

リストのアンパック

lst = ["ABC", 100, "XYZ"]
a, n, x = lst
print(a, n, x)      # ABC 100 XYZ
リストの要素を分解(アンパック)して要素に対応する変数に一括で代入できます。
変数0, 変数1, ... , 変数n = [要素0, 要素1, ... , 要素n]
代入される変数の列は変数からなるタプルなので、リストからタプルへの要素ごとの変数の代入になります。

リストの連結

lst = ["ABC", "DEF"] + [100, 200, 300]
print(lst)      # ['ABC', 'DEF', 100, 200, 300]
リスト同士を「+」で連結してリストを作成できます。
リスト = リスト1 + リスト2

リストの拡張

lst = ["ABC", 100]
lst.extend(["DEF", 200])
print(lst)      # ['ABC', 100, 'DEF', 200]

lst = ["ABC", 100]
lst += ["DEF", 200]
print(lst)      # ['ABC', 100, 'DEF', 200]
リストのextend()メソッドは、リストに別のリストを末尾に追加して拡張します。
リストを代入演算の「+=」で別のリストを連結しても同様なことができます。「+」で連結する場合は、連結したリストを新たに生成しますが、extend()の場合はそのリストが拡張します。
リスト1.extend(リスト2)
リスト1 += リスト2
元のリスト1にリスト2が追加されて拡張します。リスト2はそのまま残ります。

リストへ要素を追加

lst = ["ABC", "DEF"]
lst.append("GHI")
print(lst)      # ['ABC', 'DEF', 'GHI']
リストのappend()メソッドは、リストの末尾に要素を1つ追加します。
リスト.append(要素)

リストへ要素を挿入

lst = ["ABC", "DEF", "JKL"]
lst.insert(2, "GHI")
print(lst)      # ['ABC', 'DEF', 'GHI', 'JKL']
リストのinsert()メソッドは、リストに要素を1つ挿入します。
指定する位置(添字)に挿入します。0の場合は先頭への挿入になります。
リスト.insert(位置, 要素)

リストから要素を削除

lst = ["ABC", "DEF", "GHI"]
lst.remove("DEF")
print(lst)      # ['ABC', 'GHI']

lst = ["ABC", "DEF", "GHI"]
del lst[1:3]
print(lst)      # ['ABC']
リストのremove()メソッドは、引数で指定する要素をリストから削除します。
同じ要素が複数存在する場合は、先頭から一致する要素が削除されます。
リスト.remove(要素)
del文によりリストの位置(添字)を指定して削除できます。位置はスライスで範囲を指定することができます。
del リスト[位置]

リストから要素を取り出し

lst = ["ABC", "DEF", "GHI", "JKL"]
print(lst.pop())        # JKL
print(lst)              # ['ABC', 'DEF', 'GHI']

lst = ["ABC", "DEF", "GHI", "JKL"]
print(lst.pop(1))       # DEF
print(lst)              # ['ABC', 'GHI', 'JKL']
リストのpop()メソッドは、リストから要素を取り出します。
取り出した要素を返し、リストから削除します。取り出す位置の指定がない場合は末尾からになります。
取り出した要素 = リスト.pop()
取り出した要素 = リスト.pop(位置)

リストから要素を検索

lst = ["ABC", "DEF", "GHI", "JKL"]
print(lst.index("GHI"))     # 2
print(lst.index("XYZ"))     # ValueError
リストのindex()メソッドは、指定する要素が存在するリスト中の位置(添字)を返します。
指定する値の要素が存在しない場合はエラー(ValueError例外)となります。
位置 = リスト.index(要素)

リストから要素の数を取得

lst = [5, 4, 9, 1, 3, 5, 6, 3, 5, 8]
print(lst.count(3))     # 2
print(lst.count(5))     # 3
print(lst.count(7))     # 0
リストのcount()メソッドは、指定する要素が含まれている数(回数)を返します。
存在する数 = リスト.count(要素)

タプル

タプルの生成

tp = ()                     # 空のタプル
tp = tuple()                # 空のタプル
tp = (10, 20, 30, 40)
tp = ("AB", "CD", "EF")
tp = (10, "AB", 20, "CD")   # 異なるデータ型のタプル
tp = (a, 200, b, 400)       # 変数のタプル
tp = 100, 200, 300          # ()はなくてもよい
tp = ("ABC",)               # 要素が1つのタプル
タプルは、複数のオブジェクトを順序付けて格納するコレクションです。タプルはリストとは異なり、要素の追加・削除など生成以降に変更はできません。
タプルは、要素をカンマ「,」で区切って並べます。多くの場合、タプルの範囲をわかりやすくするために()で囲みます。
空のタプルを生成しても要素を入れることはできません。
(要素, 要素, ...)
要素が1つのタプルの生成は「,」を末尾に付けることで、それが単一データではなくタプルであることをインタプリタに解釈させます。
リテラルのみならず、変数や演算式、関数、コレクションなどを要素にできます。

配列からのタプルの生成

tp = tuple("ABC")                   # 文字列から
print(tp)                           # ('A', 'B', 'C')
tp = tuple(b"\x01\x02")             # バイト列から
print(tp)                           # (1, 2)
tp = tuple(["ABC", 123, "DEF"])     # リストから
print(tp)                           # ('ABC', 123, 'DEF')
tp = tuple({1:"A", 2:"B"})          # 辞書から
print(tp)                           # (1, 2)
tp = tuple({"A", "B"})              # セットから
print(tp)                           # 'A', 'B'
tp = tuple(range(1, 3))             # range()から
print(tp)                           # 1, 2
tuple(x)は、xのタプルへの変換を試みます。
反復可能(イテラブル)な配列型のオブジェクトはタプルに変換できます。
タプル = tuple(配列オブジェクト)
文字列・バイト列は、1文字・1バイトのタプルになります。辞書からの場合は、キーのみからなるタプルになります。

タプルのアンパック

tp = ("ABC", 100, "XYZ")
a, n, x = tp
print(a, n, x)      # ABC 100 XYZ
タプルの要素を分解(アンパック)して要素に対応する変数に一括で代入できます。
変数0, 変数1, ... , 変数n = (要素0, 要素1, ... , 要素n)
この場合、変数の列からなるタプルへの対応するタプルの代入になります。

タプルの連結

tp = ("ABC", "DEF") + (100, 200, 300)
print(tp)       # ('ABC', 'DEF', 100, 200, 300)
タプル同士を「+」で連結したタプルを作成できます。
タプル = タプル1 + タプル2

タプルから要素を検索

タプルのindex()は、指定する要素が存在するタプル中の位置(添字)を返します。
指定する値の要素が存在しない場合はエラー(ValueError例外)となります。
tp = ("ABC", "DEF", "GHI", "JKL")
print(tp.index("GHI"))      # 2
print(tp.index("XYZ"))      # ValueError
位置 = タプル.index(要素)

タプルから要素の数を取得

tp = (5, 4, 9, 1, 3, 5, 6, 3, 5, 8)
print(tp.count(3))      # 2
print(tp.count(5))      # 3
print(tp.count(7))      # 0
タプルのcount()メソッドは、指定する要素が含まれている数(回数)を返します。
存在する数 = タプル.count(要素)

辞書

辞書の生成

dic = {}                    # 空の辞書
dic = dict()                # 空の辞書
dic = {"AB": 10, "CD": 20, "EF": 30}
dic = {1: "ABC", 2: "DEF", 3: "GHI"}
dic = {(1, 10): "ABC", (2, 20): "DEF"}
dic = {10: "ABC", "X": (1, 2)}      # 型が統一していなくてもよい
dic = dict(a = 10, b = 20, c = 30)  # 代入式から辞書を生成
辞書は、キーに対応する値の組を集めるコレクションです。辞書の要素の順番は意味を持ちません。
辞書は、{}の中に「キー:値」の組み合わせを「,」で区切って並べます。
辞書は要素の追加・削除など変更が可能です。
{キー:値, キー:値, ...}
また、dict()の引数に変数と値の代入式を列挙することで、それらの変数をキーとした辞書を生成できます。
辞書 = dict(変数=値, 変数=値, ...)
変更不可(イミュータブル)なオブジェクトをキーにできます。
キーと値は、リテラルのみならず、変数や演算式、関数、コレクションなどを設定できます。辞書内で同じ値は重複できますが、キーは重複できません。

リスト・タプルからの辞書の生成

dic = dict( [("ABC", 100), ("DEF", 200), ("GHI", 300)] )
print(dic)      # {'ABC': 100, 'DEF': 200, 'GHI': 300}

dic = dict( (["ABC", 100], ["DEF", 200], ["GHI", 300]) )
print(dic)      # {'ABC': 100, 'DEF': 200, 'GHI': 300}
dict()に、キーと値の組のリスト(タプル)からなるリスト(タプル)を与えると、辞書に変換して生成します。
辞書は要素の順番に意味を持たないので、変換元のリストやタプルの順に辞書が整列しているとは限りません。
{キー:値, キー:値, ...} = dict([(キー, 値), (キー, 値), ... ])
{キー:値, キー:値, ...} = dict(([キー, 値], [キー, 値], ... ))

キーを辞書に追加する

dic = {"a": 10, "b": 20, "d": 40}
dic["c"] = 30   # 追加
print(dic)      # {'a': 10, 'b': 20, 'd': 40, 'c': 30}
dic["c"] = 300  # 変更
print(dic)      # {'a': 10, 'b': 20, 'd': 40, 'c': 300}
辞書に存在しないキーを指定して代入を行うと、そのキーと代入した値が辞書に追加されます。
辞書[新規キー] = 値
既に存在するキーを指定して代入を行うと、値が上書き変更されます。

辞書から要素を削除

dic = {"x": 10, "y": 20, "z": 30}
del dic["y"]
print(dic)      # {'x': 10, 'z': 30}
del文により辞書のキーを指定すると、その要素を削除できます。
del 辞書[キー]

辞書の拡張

dic1 = {"a": 10, "b": 20}
dic2 = {"x": 100, "y": 200}
dic1.update(dic2)
print(dic1)     # {'a': 10, 'b': 20, 'x': 100, 'y': 200,}
辞書のupdate()メソッドは、辞書に別の辞書を取り込んで拡張します。
辞書1.update(辞書2)
元の辞書1に辞書2が追加されて拡張します。辞書2はそのまま残ります。

セット(集合)

セットの生成

se = set()                  # 空のセット
se = {5, 8, 2, 9}
se = {10, "ABC", 2.5}       # 異なるデータ型のセット
se = {a, "ABC", b, "DEF"}   # 変数のセット 
se = {"ABC"}                # 要素が1つのセット
セット(集合)は、オブジェクトの集合として扱うことができるコレクションです。セットの要素の順番は意味を持ちません。
セット(集合)は、{}の中に要素をカンマ「,」で区切って並べます。セットは要素の追加・削除など変更が可能です。
空のセットはset()で生成します。{}では辞書の生成になるのでセットの生成はできません。
{値, 値, ...}

配列からのセットの生成

se = set("ABC")                     # 文字列から
print(se)                           # {'C', 'A', 'B'}
se = set(b"\x01\x02")               # バイト列から
print(se)                           # {1, 2}
se = set([10, 20, 30, 40])          # リストから
print(se)                           # {40, 10, 20, 30}
se = set(("ABC", "DEF", "GHI"))     # タプルから 
print(se)                           # {'GHI', 'DEF', 'ABC'}
se = set({1:"A", 2:"B"})            # 辞書から 
print(se)                           # {1, 2}
se = set(range(1, 3))               # range()から
print(se)                           # {1, 2}
set(x)は、xのセットへの変換を試みます。
反復可能(イテラブル)な配列型のオブジェクトはセットに変換できます。セットは、要素の順番に意味がないので、リストやタプルの順にセットの要素が整列しているとは限りません。
セット = set(配列オブジェクト)
文字列・バイト列は、1文字・1バイトのセットになります。
辞書からの場合は、キーのみからなるセットになります。

セットへ要素を追加

se = {4, 9, 3, 8}
se.add(5)
print(se)       # {3, 4, 5, 8, 9}
セットのadd()メソッドは、セットに要素を追加します。
セット.add(要素)

セットから要素を削除

se = {8, 7, 3, 6}
se.remove(3)
print(se)       # {8, 6, 7}
セットのremove()メソッドは、引数で指定する要素をセットから削除します。
セット.remove(要素)

セットの集合演算

se1 = {"A", "B", "C", "D"}
se2 = {"C", "D", "E", "F"}
print(se1 & se2)        # {'C', 'D'}
print(se1 | se2)        # {'A', 'D', 'F', 'B', 'E', 'C'}
print(se1 - se2)        # {'A', 'B'}
print(se1 ^ se2)        # {'E', 'A', 'F', 'B'}

se1 = {5, 3, 8, 2, 7}
se2 = {3, 7}
print(se2 <= se1)       # True
print(se2 < se1)        # True
print(se1 < se1)        # False
セットは集合同士を集合演算できます。また比較演算子により、一方のセットが他方の部分集合かどうかを判定できます。
集合1 & 集合2 積集合 両方に共通する部分
集合1 | 集合2 和集合 両方を合わせた集合
集合1 - 集合2 差集合 集合1から集合2に存在するものを除く
集合1 ^ 集合2 対称差集合 両方に共通する部分以外
集合1 <= 集合2 部分集合の判定 集合1は集合2に含まれる、または同一
集合1 < 集合2 真部分集合の判定 集合1は集合2に含まれる、同一を除く

配列オブジェクト共通

添字による配列の参照

s = "あいうえ"
print(s[2])                 # 'あ'
print(s[-1])                # 'え'

bi = b"\x01\x02\x03\x04"
print(bi[2])                # 3

ba = bytearray(bi) 
ba[2] = 0xcc                # 配列の変更
print(ba)                   # bytearray(b'\x01\x02\xcc\x04')

lst = ["ABC", "DEF", "GHI"]
print(lst[1])               # DEF
lst[1] = "def"
print(lst[1])               # ["ABC", "def", "GHI"]

tp = (10, 20, 30)
print(tp[2])                # 30
tp = ([10, "A"], [20, "B"], [30, "C"])
print(tp[2][1])             # C
文字列、バイト列、リスト、タプルおよび反復可能(イテラブル)で配列のように整列しているオブジェクトは、整数の位置(添字/索引番号)で個別要素(文字・バイト)を参照できます。
添字は整数であれば、変数や式の結果、関数の戻り値でもかまいません。先頭要素は0です。「-1」とすると末尾の参照になります。
文字列[n]
バイト列[n]
リスト[n]
タプル[n]
リストとbytearray型は変更可能なので、参照した要素を上書きで代入できます。
リスト[n] = 値
配列オブジェクトが多次元の場合は、次元数だけ[]の参照を繰り返します。右の方ほど深い次元(入れ子の奥)の参照になります。
配列[n][m][...

スライス

lst = [10, 20, 30, 40, 50, 60, 70]
print(lst[0:4])             # [10, 20, 30, 40]
print(lst[3:])              # [40, 50, 60, 70]
print(lst[:3])              # [10, 20, 30]
print(lst[::2])             # [10, 30, 50, 70]
print(lst[2:6:2])           # [30, 50]
print(lst[2::2])            # [30, 50, 70]
print(lst[::-1])            # [70, 60, 50, 40, 30, 20, 10]
print(lst[:-1])             # [10, 20, 30, 40, 50, 60]
print(lst[-1])              # [70]
print(lst[::])              # [10, 20, 30, 40, 50, 60, 70] コピー
lst[2:4] = [300, 400]       # 区間へ代入
print(lst)                  # [10, 20, 300, 400, 50, 60, 70]
sta = 1
end = 4
print(lst[sta:end + 1])     # [20, 30, 40, 50] 変数で指定

tp = (10, 20, 30, 40, 50, 60, 70)
print(tp[2:6:2])            # (30, 50)

s = "あいうABC"
print(s[0:3])               # 'あいう'
bi = b"\x01\x02\xa0\xb0"
print(s[2:4])               # b'\xa0\xb0'
ba = bytearray(bi)
ba[1:3] = bytearray(b"\x22\xaa")
print(ba)                   # bytearray(b'\x01"\xaa\xb0')
文字列、バイト列、リスト、タプルおよび反復可能(イテラブル)で配列のように整列しているオブジェクトは、スライスにより部分配列を参照できます。
開始添字から停止添字の手前までの範囲を、間隔のステップ数で参照します。それらは整数であれば、変数や式の結果、関数の戻り値でもかまいません。
開始と停止の添字の先頭は0からで、-1で末尾を指定できます。間隔が負数の場合は、停止から開始の方向へ逆順になります。
配列[開始添字:停止添字:間隔]
添字と間隔は省略でき、省略時は次のように適用されます。
開始省略 0
停止省略 末尾
間隔省略 1
スライスの参照で返る部分配列は、その配列型で新たに生成されます。
リストとbytearray型は変更可能なので、スライスで参照した部分リストを代入することで変更ができます。

文字列・バイト列・コレクションの長さ

s = "ABCDEFG"
print(len(s))               # 7
s = "あいうえお"
print(len(s))               # 5
bi = b"\x01\x02\x03\x04"
print(len(bi))              # 4
lst = [10, 20, 30, 40]
print(len(lst))             # 4
tp = (10, 20, 30, 40)
print(len(tp))              # 4
dic = {"x": 10, "y": 20, "z": 30}
print(len(dic))             # 3
se = {5, 3, 8, 2, 6}
print(len(se))              # 5
len()関数は、文字列、バイト列、各コレクションの長さ(文字数/サイズ/要素数)を取得します。
要素数 = len(配列)

コレクションのクリア

lst = ["ABC", "DEF", "GHI"]
lst.clear()
print(lst)                  # []
dic = {"a": 10, "b": 20, "c": 30}
dic.clear()
print(dic)                  # {}
se = {2, 8, 5, 3}
se.clear()
print(se)                   # set()
ba = bytearray(b"\x01\x02\x03\x04")
ba.clear()
print(ba)                   # bytearray(b'')
リスト、辞書、セット、bytearrayのclear()メソッドは、要素をすべて削除して配列を空にします。
コレクション.clear()

コレクションのコピー

lst1 = ["ABC", "DEF", "GHI"]
lst2 = lst1.copy()
print(lst2)                 # ['ABC', 'DEF', 'GHI']
dic1 = {"a": 10, "b": 20, "c": 30} 
dic2 = dic1.copy()
print(dic2)                 # {'a': 10, 'b': 20, 'c': 30}
se1 = {2, 7, 3, 5}
se2 = se1.copy()
print(se2)                  # {2, 3, 5, 7}
ba1=bytearray(b'\x01\x02\x03')
ba2=ba1.copy()
print(ba2)                  # bytearray(b'\x01\x02\x03')
リスト、辞書、セット、bytearray型のcopy()メソッドは、それらのコピーを作成して返します。
copy()メソッドで作られるのコピーは、 「浅いコピー 」と呼ばれるコピーであり、要素がコレクション型で階層になっていても、再帰的コピーはされません。
コピー = コレクション.copy()

コレクションの要素存在チェック

lst = ["ABC", 100, "UVW", 200]
print("UVW" in lst)         # True
print(300 not in lst)       # True
tp = ("ABC", 100, "UVW", 200)
print("UVW" in tp)          # True
se = {9, 3, 5, 8, 2, 1} 
print(7 not in se)          # True
dic = {"x": 10, "y": 20, "z":30}
print("a" in dic)           # False
print("a" not in dic)       # True
各コレクションに指定する要素が存在するかどうか、あるいは存在しないかどうかをin演算子/not in演算子で確認できます。結果はブール値で返ります。
辞書の場合は、キーが存在するかどうかの判定になります。
確認する要素 in 各種コレクション
確認する要素 not in 各種コレクション

イテレーション

配列のイテレーション

for c in "ABCあいう":
    print(c)                # A B C あ い う
for b in  b"\x01\x02\xa0\xb0":
    print(b)                # 1 2 160 176
for n in [10, 20, 30, 40]:
    print(n)                # 10 20 30 40
for n in (10, 20, 30):
    print(n)                # 10 20 30
for s in {30, 10, 20}:
    print(s)                # 10 20 30
文字列、バイト列、コレクションのような反復可能(イテラブル)なオブジェクトは、for文により要素を順番に参照(イテレーション)することができます。
for 変数 in コレクション:
    変数を使った処理

辞書のイテレーション

for key in {"a": 10, "b": 20, "c": 30}:
    print(key, dic[key])
a 10
b 20
c 30
辞書のイテレーションの場合、変数はキーを参照します。
for 変数 in 辞書:
    変数(キー)を使った処理
辞書のキー・値ごとにイテレーション
dic = {"a": 10, "b": 20, "c": 30}
print(dic.keys())
for key in dic.keys():      # キーを反復参照
    print(key)
print(dic.values())
for val in dic.values():    # 値を反復参照
    print(val)
dict_keys(['a', 'b', 'c'])
a
b
c
dict_values([10, 20, 30])
10
20
30
辞書のkeys()メソッド、values()メソッドは、それぞれ辞書のキーのみ/値のみからなる配列オブジェクトを生成します。
その配列は反復可能(イテラブル)なので、イテレーションで繰り返し参照できます。
キーのみの配列 = 辞書.keys()
値のみの配列 = 辞書.values()
辞書のキー・値を両方取得してイテレーション
dic = {"a": 10, "b": 20, "c": 30}
print(dic.items())
for k, v in dic.items():
    print(k, v)
dict_items([('a', 10), ('b', 20), ('c', 30)])
a 10
b 20
c 30
辞書のitems()メソッドは、辞書の各要素をキーのみと値をタプルにまとめた配列オブジェクトを生成します。
その配列は反復可能(イテラブル)なので、イテレーションで繰り返し参照できます。
イテレーションで得られるタプルをアンパックすると、キーと値の両方が参照できます。

順序を変えてイテレーション

for l in sorted([3, 1, 2, 4]):
    print(l)
for t in reversed((100, 200, 300)):
    print(t)
for d in sorted({2:"A", 3:"B", 1:"C"}):
    print(d, dic[d])
1
2
3
4
300
200
100
1 C
2 A
3 B
sorted()/reversed()関数に反復可能(イテラブル)なコレクションを与えると、そのコレクションをソート/逆転した順のリストを返します。
コレクションそのものの順番を変えるのではなく、新たに整列したコレクションを返します。
辞書の場合は、キーで整列します。
整列したコレクション = sorted(コレクション)
逆順のコレクション = reversed(コレクション)

整数範囲のイテレーション

for i in range(4):
    print(i)        # 0 1 2 3
for i in range(1, 4):
    print(i)        # 1 2 3
for i in range(0, 30, 10):
    print(i)        # 0 10 20
for i in range(10, 0, -2):
    print(i)        # 10 8 6 4 2
range()関数は、規則的な数列オブジェクトを生成して返します。
range()をイテレーションすることで、固定回数を繰り返す処理や、規則的な数列を使った処理が作れます。
range(回数)
range(開始値, 停止値)
range(開始値, 停止値, 間隔)

イテレータで繰り返し参照

it = iter([10, 20, 30, 40])
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
10
20
30
40
StopIteration
文字列、バイト列、コレクションのような反復可能(イテラブル)なオブジェクトは「イテレータ」によって先頭から順番に参照できます。
iter()関数は、反復可能なオブジェクトのイテレータオブジェクトを取得します。そのイテレータオブジェクトをnext()関数に指定して呼び出すたびに、順番に要素が参照できます。
末尾を超えて参照しようとしたときエラー(StopIteration例外)となります。
イテレータ = iter(コレクション)
次の要素 = next(イテレータ)
次の要素 = next(イテレータ)
...

条件による実行制御

条件の評価で分岐

s = "DEF"
if s != "ABC":
    print(s, "is not abc")

if s == "ABC":
    print(s, "is abc")
else:
    print(s, "is not abc")

if s == "ABC":
    print(s, "is abc")
elif s == "DEF":
    print(s, "is def")
else:
    print(s, "is not abc,def")
DEF is not abc
DEF is not abc
DEF is def
if文は、式の評価結果から得られるブール値によって実行する処理を分岐させることができます。
式の評価がTrueの場合は、if文以下のブロックを実行します。
if 条件式:
    条件がTrueの場合実行するブロック
    ・・・
式の結果がFalse場合は、elseに続くブロックを実行します。
if 条件式:
    条件がTrueの場合実行するブロック
    ・・・
else:
    条件がFalseの場合実行するブロック
    ・・・
elif文は、else-ifのようにifの条件がFalseの場合に、続けて別の条件をifで評価させることができます。
elif文は複数の条件を任意に連続させることができます。
else文とelif文は省略可能です。

三項演算

a = 12
x = "A" if a < 10 else "B"
print(x)        # B
三項演算は、条件式の評価結果により実行する式を分岐させます。
if文はブロックの処理を分岐させますが、三項演算は式を分岐させます。
x = Trueの式 if 条件式 else Falseの式

条件がTrueの間繰り返す

i = 0
while i < 5:
    print(i)
    i += 1
0
1
2
3
4
while文は、式の評価結果がTrueである間、ブロックの処理を繰り返し実行します。
繰り返しを終了するには、条件式がFalseになるか、break文で強制的に終了する必要があります。
while 条件式:
    条件がTrueの間繰り返すブロック
    ・・・

繰り返しの強制終了

i = 0
while True:
    if i >= 5:
        break
    print(i)
    i += 1
0
1
2
3
4
while文やfor文の繰り返しの中でbreak文を実行すると、その時点で繰り返しを中断し、それ以降の処理を実行せずブロックから抜けます。
break文は、ほとんどの場合if文を伴います。
while 条件式:
    ・・・
    if 式
        break
    ・・・
breakで中断しなかった場合のelse
num = (3, 8, 2, 9)
for i in num: 
    if i >= 10:
        break
    print(i)
else:
    print("num<10")
3
8
2
9
num<10
while文やfor文に対応するelse文のブロックに、繰り返し処理がbreak文によって中断しなかった場合の処理を実行させることができます。
while 条件式:
    ・・・
    if 式
        break
    ・・・
else:
    breakで中断しなかった場合の処理
    ・・・

繰り返しの継続

i = 0
while i < 10:
    i += 1
    if i % 2 != 0:
        continue
    print(i)
2
4
6
8
10
while文やfor文の繰り返しの中でcontinue文を実行すると、その時点でそれ以降の繰り返しの処理を放棄して、次の条件式の評価に戻ります。
while 条件式:
    ・・・
    if 式
        continue
    ・・・

条件の評価演算

while True:
    print("true")       # 永久ループ

if not "":              # 空文字はFalseと等価
    print("not none")

a = 10
b = 20
if a > 5 and b <= 30:   # 論理演算
    print(a, b)
if a > 5 or b <= 10:
    print(a, b)
if not (a > 10 or b < 20):
    print(a, b)
true
not none
10 20
10 20
10 20
if文やwhile文は、条件式の評価結果が最終的にブール値のTrueなのかFalseなのかで分岐または繰り返します。
条件式は最終的にブール値で評価できるならば、式は比較演算に限らず論理演算や関数の戻り値、ブール値と等価な変数やリテラルでかまいません。条件式に直接ブール値を指定すれば、常にその条件で実行します。
while True:
    常に繰り返す
    ・・・
次のように、データの状態によってブール値と等価に評価できます。
データ True False
数値 0以外 0
文字列 空文字でない 空文字
リスト等コンテナ 内容がある 内容が空
None - None
条件式をand/or/notの論理演算で結合することで、「AまたはB」「CかつD」「Eではない」のような条件評価ができます。

内包表記

内包表記

lst = [n * 10 for n in range(0, 5)]
print(lst)

lst = [n * 10 for n in range(0, 5) if n != 3]
print(lst)
[0, 10, 20, 30, 40]
[0, 10, 20, 40]
内包表記の構文により、イテラブルな配列オブジェクトを反復参照し、それを演算などで加工して新たなコレクションを生成することができます。
通常のイテレーションで数列のリストを生成するには、おおよそ次のようになりますが、内包表記ならばリストの内部で数列を生成できます。
lst = []
for n in range(0, 5):
    lst.append(n * 10)
[ 変数を使った式 for 変数 in イテラブルなオブジェクト ]
[ 変数を使った式 for 変数 in イテラブルなオブジェクト if 変数を使った条件式]
これらはfor文で次のように置き換えられます。
for n in イテラブルな配列:
    nを使った式

for n in イテラブルな配列:
    if nを使った条件式:
        nを使った式
辞書・セットの内包表記
dic = {n: n * 10 for n in range(0, 5)}
print(dic)      # {0: 0, 1: 10, 2: 20, 3: 30, 4: 40}

tp = (("A", 10), ("B", 20), ("C", 30))
dic = {k: v for k, v in tp} 
print(dic)      # {'A': 10, 'B': 20, 'C': 30}
リストと同様に辞書を内包表記で生成できます。キーと値の組み合わせで初期化します。
{ キー:値 for 変数 in イテラブルなオブジェクト }
se = {n for n in range(0, 5)}
print(se)       # {0, 1, 2, 3, 4}
また同様にセットを内包表記で生成できます。
{ 値 for 変数 in イテラブルなオブジェクト }

なにもしない処理

なにもしない処理

if a > 10: 
    pass    # なにもしない(空行にはできない)
else:
    print(a)

def funcdummy():    # 処理がない関数
    pass
pass文は何もしません。
インタプリタはソースコード構造を解析できないので、if文や関数的などでブロックが続くことが期待される構文では、ブロックで実行する処理がなくても、何らかの文が続かなくてはなりません。

関数

関数定義

def func(arg1, arg2):
    x = (arg1 + arg2) / 2
    print(x)
    return x
def文により、関数を定義します。defに続き、関数名と引数リストを定義します。
関数名と引数名は、変数名と同じ命名規則に従います。関数の処理をインデントによるブロックで記述します。
引数のデータ型は関数呼び出しで与えられたデータで決定するので指定しません。引数が不要ならば省略できます。
関数はreturn文で戻り値を返却します。戻り値の型は定義せず、return文で戻るデータで決定します。
return文の戻り値は省略でき、その場合は戻り値を返さずに関数が返ります。return文は定義中に複数存在してかまいません。関数のブロックの最後に達した時点でreturn文がなくても自動的に返ります。
def 関数名(引数, 引数, ...):
    処理
    ...
    return 戻り値
def 関数名():    引数なし
    ...
    return      戻り値なし
    ...
    if (..)
        return      複数個所でreturn
    ...
    ...         ブロック末尾で自動的に返る

関数呼び出し

def func1():
    print("Invoked")

func1()         # Invoked

def func2(a):
    x = a * 10  
    return x 

a = func2(5)
print(a)        # 50

def func3(a, b):
    return a * b

x = func3("A", 5)
print(x)        # AAAAA
関数定義した関数は、定義された引数に従った引数を与えて関数名で呼び出します。
引数のない関数は引数を指定せずに呼び出します。
戻り値が返る関数は、関数呼び出し自体が戻り値を参照します。
関数の戻り値を変数に代入したり、演算子の中に含めたり、コレクションの初期化要素にできます。
関数名(引数, 引数,...)
関数名( )

戻り値のアンパック

def calc(x, y):
    m = x * y
    a = x + y
    s = x - y
    return  m, a, s

c = calc(9, 5)
print(c)            # (45, 14, 4)

a, b, c = calc(3, 8)
print(a, b, c)      # 24 11 -5
戻り値はreturn文で1つのオブジェクトしか返却できませんが、リストやタプルを戻り値にすれば、複数データをまとめて返却できます。さらに、呼び出し側がアンパックで戻り値を代入すると、複数戻り値を返す関数のように振舞います。

デフォルト引数

def func(a, b = 10):
    return a * b

x = func(3)
print(x)        # 30
x = func(3, 2)
print(x)        # 6
関数の定義で引数にデフォルト値指定することで、関数を呼び出すときその引数を省略できます。
省略した引数はデフォルト値が自動的に与えられます。省略しない場合は呼び出しで与えられたものが適用されます。
def 関数(引数1=デフォルト値, 引数2=デフォルト値, ...):
デフォルトを設定した引数以降は、全てデフォルト引数で定義しなければなりません。また、呼び出し側が省略できるのは末尾側であり、省略した後に省略しない引数は続けられません。

キーワード引数

def func(a, b = 20, c = 10):
    return a * b / c 

x = func(10, c=4)
print(x)                # 50.0
x = func(10, b=2)
print(x)                # 2.0
x = func(c = 2, a = 4)
print(x)                # 40.0
キーワード引数により、関数呼び出し時の引数を、関数定義の順番(位置引数)に従わず順不同に指定することができます。
キーワード引数は、関数呼び出し時の引数に「引数名=値」のように指定します。
ret = 関数(引数名2=値, 引数名1=値, ...)
順不同に指定できるキーワード引数に対して、定義順に指定する通常の引数指定を位置引数と呼びます。
引数の先頭から位置引数を与え、途中からキーワード引数で呼び出すこともできます。
ret = 関数(引数1, 引数2, 引数4=値, 引数3=値)
キーワード指定した引数から右に定義されている引数でデフォルト設定されてないものは、すべてキーワード引数で呼び出す必要があります。
全ての引数にデフォルト値を定義すると、キーワード引数により必要な引数だけを選んで呼び出すことができます。

引数のタプル参照

def func(*args):
    for x in args:
        print(x)        # 'A' 20

func("A", 20)
関数定義で引数名の頭に「*」付けた引数は、それ以降の引数をタプルでまとめて参照できます。
このような引数を定義するときは一般的に「args」という名前にする習慣があります。
def 関数(*args):
    argsは引数列のタプル
位置引数とタプル参照を両方定義
def func(a, *args):
    for x in args:
        print(x * a)    # 50 80 30 

func(10, 5, 8, 3)
先頭側は位置引数で、途中以降からタプルの引数にできます。この場合、位置引数はタプルの中には含まれません。
関数呼び出しにタプルを与え引数展開
def func(a, b, c):
    print(a, b, c)      # 10 20 30

tp=(10, 20, 30)
func(*tp)
呼び出し側でタプルに「*」をつけて引数に与えることで、タプルの要素を展開して引数に与えることができます。
タプル = (引数1, 引数2, ...)
x = 関数(*タプル)

引数の辞書参照

def func(**kwargs):
    print(kwargs)       # {'arg1': 'A', 'arg2': 20}

func(arg1="A", arg2=20)
関数定義で引数名の頭に「**」付けた引数は、キーワード引数で渡された引数を辞書として参照できます。辞書のキーが変数名で、値が引数の値です。
このような引数を定義するときは一般的に「kwargs」という名前にする習慣があります。
def 関数(**kwargs):
    argsは引数の辞書
位置引数とタプル参照と辞書参照の混在
def func(a, b, *args, **kwargs):
    print(a, b)     # 10 20
    print(args)     # (30,)
    print(kwargs)   # {'d': 40} 10と20と30は含まれない

func(10, 20, 30, d=40)
def func(a, b, *args, **kwargs):
    print(a, b)     # 10 20
    print(args)     # ()
    print(kwargs)   # {'c': 30, 'd': 40} b=20は含まれない

func(10, b=20, c=30, d=40)
kwargsは位置引数をキーワードで指定されたものは含みません。同様にタプルで参照するargsも位置引数は含みません。
引数のタプルと辞書を組み合わせれば、あらゆる与え方の引数をargsのタプルかkwargsの辞書のいずれかで参照できます。
def 関数(*args, **kwargs):
    すべての引数をargsかkwargsで参照できる
関数呼び出しに辞書を与え引数展開
def func(a, b):
    print(a, b)     # 20 30

dic = {"a":20, "b":30}
func(**dic)
呼び出し側で辞書に「**」をつけて引数に与えることで、辞書のキーを引数名として展開して引数に与えることができます。
辞書 = {"引数1":値1, "引数2":値2, ...}
x = 関数(**辞書)

関数オブジェクト

def func():
    print("ABC")

f = func
f()             # ABC

def func1():
    print("ABC")

def func2():
    print("OPQ")

flst = [func1, func2]
flst[0]()       # ABC
flst[1]()       # OPQ
定義した関数を変数に代入し、その変数を関数として呼び出すことができます。
関数定義はデータと同様にオブジェクトとして扱うことができ、例えばリストの要素にもできます。
変数 = 関数名
変数名(引数)
関数定義を関数の引数に与える
def add(a, b):
    return a + b

def calc(func, a, b):
    return func(a, b)

x = calc(add, 7, 10)
print(x)        # 17
関数定義は、関数の引数に与えることができます。

ラムダ式(無名関数)

f = lambda x: x * 10
print(f(7))     # 70
ラムダ式は、lambdaに続く引数とひとつの文からなる関数を即時に生成します。
def文による関数定義とは異なり無名関数なので、関数名で繰り返し呼び出すことはできません。ラムダ式を変数などに代入して参照を保持しなければ、その場で定義は消滅します。
lambda 引数, 引数,…: 式
ラムダ式を定義即呼び出し
a = (lambda x, y: x * y)(7, 10)
print(a)        # 70
ラムダ式を変数に代入せずに、定義してすぐに呼び出すことができます。

関数の関数内定義

def func(a):
    def ifunc(x):
        print ("x =", x)
    ifunc(a)
func(10)        # x = 10 
関数定義の中で、関数を定義できます。関数定義のブロックで、中で定義した関数を呼び出すことができます。
def func():
    def ifunc(x):
        print ("x =", x)
    return ifunc
rf = func()
rf(10)      # x = 10 
関数定義の中で定義した関数を、戻り値として呼び出し元に返すことができます。呼び出し側では、その戻り値を関数オブジェクトとして呼び出すことができます。

関数と変数のスコープ

def add(a, b):
    x = a + b       # subのxとは関係ない
    return x

def sub(a, b):
    x = a - b       # addのxとは関係ない
    return x
関数定義の中の変数は関数定義の中だけにスコープが限定されます。同名の変数名がほかの関数定義で使われていても、それらは関数のローカルスコープで閉じています。

関数内のグローバル変数の変更

name = "Brown" 
def func1():
    print(name)
func1()             # Brown

def func2(n):
    name = n        # ローカル変数nameを生成
    print(name)     # James
func2("James")
print(name)         # Brown

def func3(n):
    global name
    name = n        # グローバル変数の変更
    print(name)     # James
func3("James")
print(name)         # James
関数定義内で関数外の変数「グローバル変数」を変更する場合は、関数定義の先頭に変数をglobal宣言します。
関数定義内でグローバル変数を参照できます。しかし関数定義内でグローバル変数への代入などで変更しようとすると、その変数はローカル変数として新たに生成されてしまうので、グローバル変数の変更にはなりません。
そのためにglobal宣言で、それが関数外のものであることを明示する必要があります。
def 関数():
    global グローバル変数名
    グローバル変数 = ...

例外処理

例外の捕捉

try:
    a = 10/0
    print(a)    # 直前で例外なので実行されない
except:
    print("Exception")
print("Continue")
Exception
Continue
スクリプトの実行を継続できない事象が発生したとき「例外」が送出されます。例外送出時は標準ではスクリプトの実行を直ちに停止させます。
スクリプトの任意の区間で送出される例外を捕捉して、それに対処する処理ブロックへジャンプさせることでスクリプトを止めずに継続させることができます。
try文からexcept文の間を例外発生を監視し、その区間で例外発生したときは直ちにexcept文のブロックへジャンプします。exceptのブロックを実行した後は、try-exceptから出て処理を継続します。
try:
    例外を捕捉したい処理区間
except:
    例外発生時の処理
例外のelseブロックとfinallyブロック
try:
    a = 10/0
except:
    print("zero div")
else:
    print("No error")
finally:
    print("Done")
zero div
Done
try-exceptの区間で例外が発生しなかった場合のみ実行する処理をelseブロックに記述できます。
また、exceptで補足した場合とそうでないelseブロックを実行した場合の両方の場合に共通して最後に実行する処理を、finallyブロックに記述できます。

指定の例外を捕捉

try:
    a = 10/1
    print(a)
    d = {"AB":20}
    print(d["CD"])
except ZeroDivisionError: 
    print("zero div")
except Exception as e:
    print(type(e))
<class 'KeyError'>
例外は、プロセス終了を除く発生の要因ごとに、Exceptionクラスをスーパークラスとするサブクラスとして定義されています。
exceptに続けて例外クラス名を指定すると、その例外のみを捉えます。また、Exceptionクラスを指定すると、全てのクラスを補足できます。
except 例外クラス名:    ※指定する例外
except:                 ※すべての例外
except Exception:       ※すべての例外
補足した例外クラスのインスタンスをasに続く変数に格納することができます。
その変数をprint()で表示したり、type()でクラス名を調べることで、例外の詳細を知ることができます。
except 例外クラス名 as 変数:
主な例外クラス
例外 例外の説明
KeyboardInterrupt Ctrl-Cが入力された
StopIteration これ以上反復する要素がない(next()関数が終端に達したなど)
ArithmeticError 算術演算関係のエラー
  OverflowError 計算結果が表現しきれない大きい値になった
  ZeroDivisionError 0での割り算が行われた
AttributeError 属性の参照や代入でのエラー(ImportErrorが出る状況と似ている)
EOFError input()の入力待ちでEOF(Ctrl-zやCtrl-d)になった
ImportError インポート失敗(モジュールと同名ファイルが競合しているなど)
LookupError キーや添字の参照で違反
  IndexError 添字が範囲外
  KeyError キーが存在しない
NameError ローカル・グローバルに名前が見つからなかった
OSError システム関係のエラー
  FileExistsError 既に存在するファイルを作成しようとした
  FileNotFoundError ファイルやディレクトリが存在しない
  PermissionError ファイル操作のアクセス権違反
  TimeoutError システム関数がタイムアウトした
RuntimeError 分類できないエラー
SyntaxError 文法エラー
  IndentationError インデントが正しくない
TypeError データ型の不一致(整数と文字列で足し算しようとしたなど
ValueError 値が異常(数値を表していない文字列を数値変換しようとしたなど

ライブラリの利用

ライブラリをインポート

import math

print(math.pow(5, 2))       # 25.0
import文により、Pythonにインストールされているライブラリ(パッケージ)のモジュール名を指定しインポートできます。
インポートしたモジュールの内容は、それ以降のスクリプトで利用できます。モジュール名を名前空間として、そのモジュールの定義されたクラス、関数、変数を参照できます。
import モジュール名

モジュール名.クラス
モジュール名.関数()
モジュール名.変数

モジュール名の省略

from math import pow, sqrt, pi

print(pow(5, 2))        # 25.0
print(pi)               # 3.141592653589793
print(sqrt(2))          # 1.4142135623730951
import文でインポートしたモジュールを利用するとき、デフォルトではモジュール名の名前空間を指定する必要があります。
from~import文により、モジュールから参照したいシンボル名(関数、クラス、変数)を明示的に指定することで、利用時にそれらのモジュール名を省略できます。
from モジュール名 import 関数, クラス, 変数, ... 
列挙するシンボル名を「*」で置き換えると、そのモジュール内の全てを一括指定できます。
その場合、そのモジュールを現在のスクリプトに書き写したかのように使うことができます。
from モジュール名 import * 

モジュール名の別名

import math as m

print(m.pow(5, 2))      # 25.0
print(m.pi)             # 3.141592653589793
インポートするモジュールを別名を付けて参照できます。インポートするモジュールがパッケージを含めた長い名前を書きやすくします。
import モジュール名 as 別名

コマンドライン引数

コマンドライン引数の参照

import sys

print(len(sys.argv))
for arg in sys.argv:
    print(arg)
$ python3 cmd.py aaa 123 xxx
4
cmd.py
aaa
123
xxx
Pythonを実行するとき、コマンドラインにパラメータを指定できます。
コマンドラインパラメータは、sysモジュールのsys.argvから文字列のリストとして参照できます。従って、sysモジュールをインポートする必要があります。
sys.argvのリストは先頭からpython3コマンドに続けて指定したものがそのまま格納されます。多くの場合最初はスクリプトファイルなので、先頭のsys.argv[0]はそのファイル名になります。
import sys
sys.argv[0]     スクリプトファイル名
sys.argv[1]       引数1
sys.argv[2]      引数2