Pythonが提供する標準的な反復可能オブジェクトとして、文字列、リスト、タプル、辞書、集合の操作をギュギュッとまとめた。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
今回はPythonを使う上では避けては通れない、文字列、リスト、タプル、辞書、集合の定義とその操作(演算子、組み込み関数、メソッド)を見ていく(本稿ではfrozenset、バイト列などは省略する)。
文字列(str)、リスト(list)、タプル(tuple)、辞書(dict)、集合(set)には次のような特性がある。
特性 | str | list | tuple | dict | set |
---|---|---|---|---|---|
変更可能 | × | ○ | × | ○ | ○ |
変更不可能 | ○ | × | ○ | × | × |
要素に順序がある | ○ | ○ | ○ | × | × |
要素に順序がない | × | × | × | ○ | ○ |
要素(キー)の重複 | ○ | ○ | ○ | × | × |
要素の種類 | 文字 | 任意 | 任意 | キー/値の組 | 任意 |
文字列/リスト/タプル/辞書/集合の定義 |
また、これらは組み込み関数もしくはリテラルの形で定義できる。以下に定義例を示す。
# 文字列の定義
s = 'foo' # 文字列リテラルはシングルクオート/ダブルクオートなどで囲む
print('s:', s) # 'foo'
s = str([0, 1, 2]) # str関数は他のオブジェクトの文字列表現を作成する
print('s:', s) # '[0, 1, 2]'
# リストの定義
l = ['foo', 'bar'] # リストリテラルは[]で囲む
print('l:', l) # ['foo', 'bar']
l = list('foo') # list関数に文字列(反復可能オブジェクト)を渡す
print('l:', l) # ['f', 'o', 'o']
# タプルの定義
t = (0, 1, 2) # タプルリテラルは()で囲む
print('t:', t) # (0, 1, 2)
t = () # 空のタプル
print('t:', t) # ()
t = (0, ) # 要素を1つだけ持つタプル
print('t:', t) # (0,)
t = tuple(l) # tuple関数にリスト(反復可能オブジェクト)を渡す
print('t:', t) # ('f', 'o', 'o')
# 辞書の定義
d = {'a': 'A', 'b': 'B', 'c': 'C'} # 辞書リテラルは{}内にキー/値の組を書く
print('d:', d) # {'a': 'A', 'b': 'B', 'c': 'C'}
d = dict(foo='FOO', bar='BAR', baz='BAZ') # dict関数にキーワード引数を渡す
print('d:', d) # {'foo': 'FOO', 'bar': 'BAR', 'baz': 'BAZ'}
d = dict([('a', 'A'), ('b', 'B')]) # キーと値のタプルを要素とするリストを渡す
print('d:', d) # {'a': 'A', 'b': 'B'}
# 集合の定義
s = {0, 1, 2} # 集合リテラルは{}で囲む
print('s:', s) # {0, 1, 2}
s = set('foo') # set関数に文字列(反復可能オブジェクト)を渡す
print('s:', s) # {'f', 'o'}:集合は要素の重複を許さない
リスト、辞書、集合については内包表記を使って定義することも可能だ。
# リスト内包表記
l = [x for x in range(5)] # [0, 1, 2, 3, 4] == list(range(5))
l = [x ** 2 for x in l] # [0, 1, 4, 9, 16]
# 辞書内包表記
d = {x: x * 2 for x in range(3)} # {0: 0, 1: 2, 2: 4}
# 集合内包表記
s = {x ** 2 for x in range(3)} # {0, 1, 4}
なお、これらのオブジェクトの詳細については以下を参照されたい。
以下では、これらのオブジェクトに共通する操作、オブジェクトに固有の操作を順に見ていこう。
以下に文字列(str)、リスト(list)、タプル(tuple)、辞書(dict)、集合(set)に対して可能な演算と、それらを引数に取る組み込み関数を一覧し、それぞれのデータ型でその操作を行えるかを○(可能)と×(不可能)で示す。以下の表の「操作」列では「iter」を反復可能オブジェクトとし、「x」はその要素と同じ型の値、「n」「i」「j」「k」「func」を乗算やインデクシング、スライシング、その他の操作で使用する値とする。なお、「dict」列で「○」となっているものは、辞書の「キー」を対象とすることには注意しよう(例えば、「'x' in {'A': 'a', 'X': 'x'}」はFalseとなるが、これは辞書に「'x'」というキーがないからだ)。一部の操作では、指定可能な引数を省略しているものもある。
操作 | 説明 | str | list | tuple | dict | set |
---|---|---|---|---|---|---|
x in iter | xが存在するかどうか | ○ | ○ | ○ | ○ | ○ |
x not in iter | xが存在しないかどうか | ○ | ○ | ○ | ○ | ○ |
iter1 + iter2 | iter1とiter2を結合した結果を得る | ○ | ○ | ○ | × | × |
iter1 += iter2 | iter1の末尾にiter2を結合 | × | ○ | × | × | × |
iter * n、n * iter | iterのn回の繰り返し | ○ | ○ | ○ | × | × |
iter *= n | iterをn回繰り返したものをiterに代入 | × | ○ | × | × | × |
iter[i] | iterのi番目の要素 | ○ | ○ | ○ | ○ | × |
iter[i:j] | iterのi番目からj番目の要素 | ○ | ○ | ○ | × | × |
iter[i:j:k] | iterのi番目からj番目の要素(k個おきに) | ○ | ○ | ○ | × | × |
iter[i] = x | iterのi番目の要素にxを代入 | × | ○ | × | ○ | × |
iter1[i:j] = iter2 | iter1[i:j]をiter2に置き換える | × | ○ | × | × | × |
iter1[i:j:k] = iter2 | iter[i:j:k]をiter2に置き換える(両者の要素数が同じである必要がある) | × | ○ | × | × | × |
del iter[i] | iter[i]の要素を削除 | × | ○ | × | ○ | × |
del iter[i:j] | iter[i:j]の要素を削除 | × | ○ | × | × | × |
del iter[i:j:k] | iter[i:j:k]の要素を削除 | × | ○ | × | × | × |
all(iter) | iterの要素が全て真かどうか | ○ | ○ | ○ | ○ | ○ |
any(iter) | iterのいずれかの要素が真かどうか | ○ | ○ | ○ | ○ | ○ |
enumerate(iter, i=0) | 「(index, item)」というタプルを返すイテレータを取得 | ○ | ○ | ○ | ○ | ○ |
filter(func, iter) | iterの要素に対してfuncを実行し、その結果が真となるものだけを返送するイテレータを取得 | ○ | ○ | ○ | ○ | ○ |
len(iter) | iterの要素数 | ○ | ○ | ○ | ○ | ○ |
map(func, iter) | iterの要素に対してfuncを実行し、その結果を返送するイテレータを取得 | ○ | ○ | ○ | ○ | ○ |
max(iter) | iterで最大の要素 | ○ | ○ | ○ | ○ | ○ |
min(iter) | iterで最小の要素 | ○ | ○ | ○ | ○ | ○ |
reversed(iter) | 順序を持つiterの要素を逆順に取り出すイテレータを取得 | ○ | ○ | ○ | × | × |
sorted(iter, key=None) | keyに指定された関数でiterの要素(辞書の場合はキー)を処理したものをキーとして、iterを並べ替えた新しいオブジェクトを取得 | ○ | ○ | ○ | ○ | ○ |
sum(iter) | iterの要素の和を求める。要素は数値である必要がある | ○ | ○ | ○ | ○ | ○ |
zip(*iter) | iterに指定された1つ以上の反復可能オブジェクトから、同じインデックスを持つ要素をまとめたタプルを返送するイテレータを取得 | ○ | ○ | ○ | ○ | ○ |
反復可能オブジェクトの操作(演算子、del文、組み込み関数) |
以下に例を示す。
# in演算子、not in演算子
print("'y' in 'Python':", 'y' in 'Python') # True
print("0 not in [1, 2, 3]:", 0 not in [0, 1, 2, 3]) # False
# +演算子
print('(0, 1, 2) + (3, 4):', (0, 1, 2) + (3, 4)) # (0, 1, 2, 3, 4)
# +=演算子
iter1 = list(range(4))
print('iter1:', iter1) # [0, 1, 2, 3]
iter1 += [4, 5]
print('iter1 += [4, 5]:', iter1) # [0, 1, 2, 3, 4, 5]
# *演算子
print("'Py' * 2:", 'Py' * 2) # 'PyPy'
# *=演算子
iter = ['foo', 'bar']
print('iter:', iter) # ['foo', 'bar']
iter *= 3
print('iter *= 3:', iter) # ['foo', 'bar', 'foo', 'bar', 'foo', 'bar']
# []演算子
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
print('iter[2]:', iter[2]) # 2
print('iter[1:3]:', iter[1:3]) # [1, 2]
print('iter[3:-1]:', iter[3:-1]) # [3]
print('iter[::2]:', iter[::2]) # [0, 2, 4]
# []演算子(代入)
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
iter[2] = 100
print('iter[2] = 100:', iter) # [0, 1, 100, 3, 4]
iter = {'a': 'A', 'b': 'B', 'c': 'C'}
print('iter:', iter) # {'a': 'A', 'b': 'B', 'c': 'C'}
iter['c'] = 'c'
print("iter['c'] = 'c':", iter) # {'a': 'A', 'b': 'B', 'c': 'c'}
iter1 = list(range(5))
print('iter1:', iter1) # [0, 1, 2, 3, 4]
iter2 = [10, 20]
print('iter2:', iter2) # [10, 20]
iter1[1:3] = iter2 # インデックス1と2の要素を[10, 20]で置き換える
print('iter1[1:3] = iter2:', iter1) # [0, 10, 20, 3, 4]
print('iter1:', iter1) # [0, 10, 20, 30, 4]
iter2 = [100, 200, 400]
print('iter2:', iter2) # [100, 200, 400]
iter1[0:5:2] = iter2
print('iter1[0:5:2] = iter2:', iter1) # [100, 10, 200, 3, 400]
# del文
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
del iter[3]
print('del iter[3]:', iter) # [0, 1, 2, 4]
del iter[0:1] # del iter[0:1]はiter[0]のみを削除
print('del iter[0:1]:', iter) # [1, 2, 4]
del iter[::2] # 0番目の要素と2番目の要素を削除
print('del iter[::2]:', iter) # [2]
# all関数/any関数
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
print('all(iter):', all(iter)) # False:iter[0]==0は偽と評価される
print('any(iter):', any(iter)) # True:iter[0]以外は真と評価される
# enumerate関数
iter = 'iter'
for (idx, ch) in enumerate(iter):
print(f"iter[{idx}] = '{ch}'") # "iter[0] = 'i'"、"iter[1] = 't'"、……
# filter関数
iter = [2, 7, 8, 10, 1]
print('iter:', iter)
result = list(filter(lambda x: x % 2 == 0, iter)) # 偶数のみからなるリスト
print('list(filter(lambda x: x % 2 == 0, iter)):', result) # [2, 8, 10]
# len関数
iter = {chr(x + ord('a')): chr(x + ord('A')) for x in range(26)}
print('iter:', iter) # {'a': 'A', 'b': 'B', ……, 'y': 'Y', 'z': 'Z'}
print('len(iter):', len(iter)) # 26
# map関数
iter = list('iter')
print('iter:', iter) # ['i', 't', 'e', 'r']
result = list(map(lambda x: chr(ord(x) - 32), iter)) # 32=ord('a') - ord('A')
print('list(map(lambda x: chr(ord(x) - 32), iter)):', result) # ['I', 'T', 'E', 'R']
# max関数/min関数
iter = set(range(10))
print('iter:', iter) # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
print('max(iter):', max(iter)) # 9
iter = 'string'
print('iter:', iter) # 'string'
print('min(iter):', min(iter)) # 'g'
# reversed関数
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
print('list(reversed(iter)):', list(reversed(iter))) # [4, 3, 2, 1, 0]
# sorted関数
iter = 'Python'
print('iter:', iter) # 'Python'
result = ''.join(sorted(iter)) # ASCII順に並べ替え
print("''.join(sorted(iter)):", result) # 'Phnoty'
result = ''.join(sorted(iter, key=str.upper)) # 全てを大文字化した値で並べ替え
print("''.join(sorted(iter, key=str.upper)):", result) # 'hnoPty'
# sum関数
iter = list(range(5))
print('iter:', iter)
print('sum(iter):', sum(iter)) # 10
iter = '012345'
print('iter:', iter)
print('sum([int(x) for x in iter]):', sum([int(x) for x in iter])) # 15
# zip関数
for (x, y) in zip([0, 1, 2], 'str'):
print(x, y) # '0 s'、'1 t'、'2 r'
反復可能オブジェクトには変更可能(ミュータブル)なものと、変更不可能(イミュータブル)なものがある。また、要素が順序を持つもの(シーケンス)と持たないものがある。こうした特性の違いに応じて、それらに対して呼び出し可能なメソッドが決まる。例えば、文字列とタプルはともに変更不可能な反復可能オブジェクトであるため、呼び出せるのはindexメソッドとcountメソッドのみとなる(変更可能かつ要素が順序を持つ反復可能オブジェクトはリストのみであることから、以下の表に示すメソッドの多くはリストのみでサポートされている)。また、辞書と集合はclearメソッドなど幾つかのメソッドを提供している。
以下に文字列、リスト、タプル、辞書、集合で呼び出し可能/呼び出し不可能なメソッドを一覧する。以下の表の「メソッド」列では「iter」を反復可能オブジェクトとし、「x」はその要素と同じ型の値、「i」を要素のインデックスを表す値とする。
メソッド | 説明 | str | list | tuple | dict | set |
---|---|---|---|---|---|---|
iter.index(x, i, j) | iter(のi番目からj番目)の要素で最初にxが登場する位置 | ○ | ○ | ○ | × | × |
iter.count(x) | iterにxが何個含まれているか | ○ | ○ | ○ | × | × |
iter1.append(x) | iterの末尾にxを追加 | × | ○ | × | × | × |
iter.clear() | iterの内容を全て削除 | × | ○ | × | ○ | ○ |
iter.copy() | iterの浅いコピーを作成 | × | ○ | × | ○ | ○ |
iter1.extend(iter2) | iter1の末尾にiter2を結合 | × | ○ | × | × | × |
iter.insert(i, x) | iterのi番目の位置にxを挿入 | × | ○ | × | × | × |
iter.pop(i) | iterの先頭(またはi番目)の要素を削除して、その値を戻り値とする 辞書の場合はiで示されるキーを削除し、その値を戻り値とする 集合の場合は引数を取らず、集合の任意の要素を削除して、それを戻り値とする |
× | ○ | × | ○ | ○ |
iter.remove(x) | iterから指定された要素xを削除する。戻り値はなし | × | ○ | × | × | ○ |
iter.reverse(x) | iterをインプレースで逆順に並べ替える | × | ○ | × | △ | × |
以下に例を示す。
# indexメソッド
iter = 'foobarbaz'
print('iter:', iter)
print("iter.index('a'):", iter.index('a')) # 4
print("iter.index('a', 5, 8):", iter.index('a', 5, 8)) # 7
# countメソッド
iter = (0, 1, 2) * 2
print('iter:', iter) # (0, 1, 2, 0, 1, 2)
print('iter.count(0):', iter.count(0)) # 2
# appendメソッド
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
iter.append(5) # 戻り値はないので別に実行しておく
print('iter.append(5):', iter) # [1, 2, 3, 4, 5]
iter.append([6])
print('iter.append([6]):', iter) # [1, 2, 3, 4, 5, [6]]
# clearメソッド
iter = {'a': 'A', 'b': 'B'}
print('iter:', iter) # {'a': 'A', 'b': 'B'}
iter.clear() # 戻り値はないので別に実行しておく
print('iter.clear():', iter) # {}
# copyメソッド
iter1 = {0, 1, 2, 3}
print('iter1:', iter1) # {0, 1, 2, 3}
iter2 = iter1.copy()
print('iter2 = iter1.copy():', iter2) # {0, 1, 2, 3}
print('iter1 == iter2:', iter1 == iter2) # True
print('iter1 is iter2:', iter1 is iter2) # False
iter1 = [[0, 1], [2, 3]]
print('iter1:', iter1) # [[0, 1], [2, 3]]
iter2 = iter1.copy() # copyメソッドは浅いコピーを作成する
print('iter2 = iter1.copy():', iter2) # [[0, 1], [2, 3]]
print('iter1 is iter2:', iter1 is iter2) # False
print('iter1[0] is iter2[0]:', iter1[0] is iter2[0]) # True
# extendメソッド
iter1 = list(range(5))
iter2 = [5, 6]
print('iter1:', iter1) # [0, 1, 2, 3, 4]
print('iter2:', iter2) # [5, 6]
iter1.extend(iter2) # 戻り値はないので別に実行しておく
print('iter1.extend(iter2):', iter1) # [0, 1, 2, 3, 4, 5, 6]
# insertメソッド
iter = [0, 1, 3, 4]
print('iter:', iter) # [0, 1, 3, 4]
iter.insert(2, 20) # 戻り値はないので別に実行しておく
print('iter.insert(2, 20):', iter) # [0, 1, 20, 3, 4]
# popメソッド
iter = list(range(5))
print('iter:', iter) # [0, 1, 2, 3, 4]
print('iter.pop():', iter.pop()) # 4
print('iter:', iter) # [0, 1, 2, 3] # 末尾の要素が削除され、取り出された
print('iter.pop(1):', iter.pop(1)) # 1
print('iter:', iter) # [0, 2, 3]:指定したインデックス位置の要素が対象
iter = {'a': 'A', 'b': 'B', 'c': 'C'}
print('iter:', iter) # {'a': 'A', 'b': 'B', 'c': 'C'}
print("iter.pop('c'):", iter.pop('c')) # 'C'
print('iter:', iter) # {'a': 'A', 'b': 'B'}
print("iter.pop('d', 'default'):", iter.pop('d', 'default')) # 'default'
iter = {1, 2, 4, 7, 9}
print('iter:', iter) # {1, 2, 4, 7, 9}
print('iter.pop():', iter.pop()) # 1
# removeメソッド
iter = [0, 1, 2] * 2
print('iter:', iter) # [0, 1, 2, 0, 1, 2]
iter.remove(2) # 戻り値はないので別に実行しておく
print('iter.remove(2):', iter) # [0, 1, 0, 1, 2]
iter = set(range(5))
print('iter:', iter) # {0, 1, 2, 3, 4}
iter.remove(2) # 戻り値はないので別に実行しておく
print('iter.remove(2):', iter) # {0, 1, 3, 4}
# reverseメソッド
iter = list(range(5))
print('iter:', iter)
iter.reverse() # 戻り値はないので別に実行しておく
print('iter.reverse():', iter) # [4, 3, 2, 1, 0]
以下では、文字列、リストなど、それぞれの反復可能オブジェクトが持つ固有のメソッドについてまとめる。
リストに固有のメソッドを以下に示す(リストは「lst」と表記)。
メソッド | 説明 |
---|---|
lst.sort(key=None, reverse=False) | lstの要素をインプレースでリストの要素を並べ替える |
リストに固有のメソッド |
表に示した通り、リストに固有のメソッドは「破壊的な」(リスト自体の要素を書き換える)sortメソッドのみだ。元のリストの順序を維持したまま、並べ替え後のリストがほしいときには組み込みのsorted関数を使用する。
引数keyは、上で見たsorted関数と同様に並べ替える際のキーを取得するために使用する。引数reverseにTrueを指定すると降順に、False(デフォルト値)を指定すると昇順に並べ替えが行われる。
以下に例を示す。
lst = ['foo', 'bar', 'baz']
print('lst:', lst) # ['foo', 'bar', 'baz']
lst.sort() # 戻り値はないので別に実行しておく
print('lst.sort():', lst) # ['bar', 'baz', 'foo']
lst = list('Python')
print('lst:', lst) # ['P', 'y', 't', 'h', 'o', 'n']
lst.sort(key=str.upper, reverse=True) # 大文字小文字の区別なしで並べ替え。逆順
print('lst.sort(key=str.upper, reverse=True):', lst) # ['y', 't', 'P', 'o', 'n', 'h']
辞書に固有のメソッドを以下に示す。以下の表では、辞書オブジェクトを「dct」と表記する。なお、辞書で実装されているメソッドや操作のうち、上で紹介したものは省略している。
メソッド | 説明 |
---|---|
dict.fromkeys(iter, value) | dictクラスのクラスメソッド。iterの要素をキーとした新しい辞書を作成する。valueが指定されれば、キーの値はvalueになる。指定しなければ、Noneになる |
dct.get(key, default=None) | keyの値を取得する。keyが辞書になければdefaultの値が返される。dct[key]のようにして値を取得しようとすると、keyがないときにはKeyError例外が発生するが、getメソッドではKeyError例外が発生しない |
dct.items() | (key, value)となるタプルを返送するビューを取得する |
dct.keys() | 辞書のキーを返送するビューを取得する |
dct.popitem() | (key, value)の組を任意(またはPython 3.7以降では辞書にキー/値の組を追加したのとは逆の順)にdctから削除して、それを戻り値とする |
dct.setdefault(key, default=None) | dctに指定したkeyがあれば、その値を戻り値とする。なければ、defaultに指定した値をkeyの値の値として、辞書にエントリを追加する(戻り値はdefaultの値) |
dct.update(other) | otherに指定した辞書、キー/値を要素とする反復可能オブジェクト、キーワード引数などを使って、dctを更新する。既存のキーが指定された場合は上書きされる |
dct.values() | dctの値を返送するビューを取得する |
辞書に固有のメソッド |
以下に幾つか例を示す。詳細な説明と例については「Python入門」の「辞書」を参照されたい。
dct = {chr(x+ord('a')): chr(x+ord('A')) for x in range(3)}
print('dct:', dct) # {'a': 'A', 'b': 'B', 'c': 'C'}
print(dct.get('f')) # None(辞書にないキーを指定)
for (key, value) in dct.items():
print(f'{key}: {value}') # 'a: A'、'b: B'、'c: C'
for key in dct.keys():
print(dct[key]) # 'A'、'B'、'C'
dct.setdefault('d', 'D')
print('dct:', dct) # {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D'}
print(dct.popitem()) # ('d', 'D')
print('dct:', dct) # {'a': 'A', 'b': 'B', 'c': 'C'}
集合に固有のメソッド/演算子を以下に示す。以下の表では、辞書オブジェクトを「st」と表記する。なお、集合で実装されているメソッドや操作のうち、上で紹介したものは省略している。
Copyright© Digital Advantage Corp. All Rights Reserved.