目的
この記事では、Pythonが扱う組込みデータ型(str、list、tuple、range、dict)の基本的な操作方法について記載する。
str型 : 文字列型
文字列(Unicode文字)の並びを表す型。
Unicodeは文字集合であり、Unicodeの符号化方式(文字コード)であるUTF-8やUTF-16と混同しないように注意。
例えば、別の文字集合であるJISX0208なら符号化方式は、ISO-2022-JP(通称JISコード)かShift-JISとなるように、文字集合に対応する符号化方式(文字コード)は決まっている。
-
型の特性
- イミュータブルオブジェクト
- イテラブルオブジェクト
- シーケンスオブジェクト
-
定義例
$ python >>> # 変数 str_a をシングルクォーテーションで囲んで定義 >>> str_a = 'abc' >>> type(str_a) <class 'str'> >>> >>> # 変数 str_b をダブルクォーテーションで囲んで定義 >>> str_b = "abc" >>> type(str_b) <class 'str'> >>> >>> # 変数 str_c をトリプルクォート(シングルクォーテーション)で囲んで定義 >>> str_c = '''hij ... klmn''' >>> print(str_c) # 定義文字として改行(\n)を認識する hij klmn >>> >>> type(str_c) <class 'str'> >>> >>> # 変数 str_d をトリプルクォート(ダブルクォーテーション)で囲んで定義 >>> str_d = """abc ... defg""" >>> print(str_d) # 定義文字として改行(\n)を認識する abc defg >>> >>> type(str_d) <class 'str'> >>>
-
エスケープの使用例
- よく使用されるエスケープシーケンス
エスケープシーケンス 説明 \\ バックスラッシュ(\\) \\' シングルクォーテーション(') \\" ダブルクォーテーション(") \n ASCII 行送り(LF) \r ASCII 復帰(CR) \t ASCII 水平タブ(TAB)
- よく使用されるエスケープシーケンス
-
主な使用例
$ python >>> # 行送りLF(改行) >>> str_a = "abcdefg\nhijklmn" >>> print(str_a) abcdefg hijklmn >>> >>> # 水平タブ(TAB) >>> str_b = "abcdefg\thijklmn" >>> print(str_b) abcdefg hijklmn >>> >>> # シングルクォーテーション(') >>> str_c = "abc'def'ghi" >>> print(str_c) abc'def'ghi >>> >>> # ダブルクォーテーション(") >>> str_d = 'abc"def"ghi' >>> print(str_d) abc"def"ghi >>>
-
ダブルクォーテーションで囲む場合、シングルクォーテーションのエスケープ(\)は省略可能
$ python >>> str_a = "This is a "string"" # エスケープがないとエラーとなる File "<stdin>", line 1 str_a = "This is a "string"" SyntaxError: invalid syntax >>> str_b = 'This is a "string"' # シングルクォーテーションで囲った場合はエスケープは不要 >>> print(str_b) This is a "string" >>>
-
シングルクォーテーションで囲む場合、ダブルクォーテーションのエスケープ(\)は省略可能
$ python >>> str_a = 'Let\'s' # エスケープがないとエラーとなる File "<stdin>", line 1 str_a = 'Let's' ^ SyntaxError: invalid syntax >>> str_a = "Let's" # ダブルクォーテーションで囲った場合はエスケープは不要 >>> print(str_a) Let's >>>
list型 : 配列型
論理型や数値型、文字列型など任意の型を配列として定義する。
-
型の特性
- ミュータブルオブジェクト
- イテラブルオブジェクト
- シーケンスオブジェクト
-
定義例
$ python >>> # 変数 list_a を空配列で定義 >>> list_a = [] >>> type(list_a) <class 'list'> >>> >>> # 変数 list_b をコンストラクタを用いて空配列で定義 >>> list_b = list() >>> type(list_b) <class 'list'> >>> >>> # 要素数と初期値を指定して定義する >>> list_c = [0]*10 >>> print(list_c) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] >>> >>> # 変数 list_d を int型の1次元配列で定義 >>> list_d = [1, 2, 3, 4, 5] >>> print(list_d) [1, 2, 3, 4, 5] >>> type(list_d) <class 'list'> >>> >>> # 変数 list_f を string型の1次元配列で定義 >>> list_f = ['a', 'b', 'c', 'd', 'e'] >>> type(list_f) <class 'list'> >>> >>> # 変数 list_g を string型とint型の2次元配列で定義 >>> list_g = [['typeA',1000], ['typeB', 2000], ['typeC', 3000]] >>> type(list_g) <class 'list'> >>>
-
list要素の取得
$ python >>> # 変数 list_a を string型の1次元配列で定義 >>> list_a = ['a', 'b', 'c', 'd', 'e'] >>> >>> # 出現回数の取得 >>> print(list_a.count('c')) 1 >>> >>> # 1番目を取得 >>> print(list_a[0]) a >>> >>> # 4番目(末尾が起点)を取得 >>> print(list_a[-2]) d >>> >>> # 1番目から3番目まで取得 >>> print(list_a[0:3]) ['a', 'b', 'c'] >>> >>> # 先頭(1番目)から最後(5番目)まで取得 >>> print(list_a[:]) ['a', 'b', 'c', 'd', 'e'] >>> >>> # 3番目から最後(5番目)まで取得 >>> print(list_a[2:]) ['c', 'd', 'e'] >>> >>> # 4番目(末尾が起点)から最後(5番目)まで取得 >>> print(list_a[-2:]) ['d', 'e'] >>> >>> # 先頭(1番目)から最後(5番目)まで一つ飛ばしで取得 >>> print(list_a[::2]) ['a', 'c', 'e'] >>> >>> # list内包表記でfor文の結果を取得 >>> list_b = [1, 2, 3, 4, 5] >>> [list_b_row for list_b_row in list_b if list_b_row > 2] [3, 4, 5] >>>
-
list要素の追加、変更、削除
$ python >>> # 末尾に要素を追加 >>> list_a = [10, 20, 30, 40, 50] >>> >>> list_a.append(60) >>> >>> print(list_a) [10, 20, 30, 40, 50, 60] >>> >>> # 5番目と6番目の間に要素を挿入 >>> list_b = [10, 20, 30, 40, 50] >>> >>> list_b.insert(5, 55) >>> >>> print(list_b) [10, 20, 30, 40, 50, 55] >>> >>> # 要素を結合 >>> list_a = ['a', 'b', 'c', 'd', 'e'] >>> list_b = [1, 2, 3, 4, 5] >>> >>> # list_aとlist_b の結合結果を表示(list_a、list_bは書き変わらない) >>> print(list_a + list_b) ['a', 'b', 'c', 'd', 'e', 1, 2, 3, 4, 5] >>> >>> # list_a の末尾に list_b を結合 >>> list_a.extend(list_b) >>> >>> print(list_a) ['a', 'b', 'c', 'd', 'e', 1, 2, 3, 4, 5] >>> >>> # 5番目の要素を変更 >>> list_c = [10, 20, 30, 40, 50] >>> list_c[4] = 55 >>> print(list_c) [10, 20, 30, 40, 55] >>> >>> # 3番目の要素を削除 >>> list_d = [10, 20, 30, 40, 50] >>> >>> list_d.pop(2) 30 >>> print(list_d) [10, 20, 40, 50] >>> >>> # 末尾の要素を削除 >>> list_e = [10, 20, 30, 40, 50] >>> >>> list_e.pop() 50 >>> print(list_e) [10, 20, 30, 40] >>> >>> # 値 x を持つ最初の要素を削除 >>> list_f = [10, 20, 30, 40, 50, 60] >>> >>> list_f.remove(40) >>> >>> print(list_f) [10, 20, 30, 50, 60] >>>
-
list要素の並び替え
$ python >>> list_a = [10, 40, 30, 20, 50] >>> >>> # 昇順に並び替え >>> list_a.sort() >>> >>> print(list_a) [10, 20, 30, 40, 50] >>> >>> # 降順に並び替え >>> list_a.reverse() >>> >>> print(list_a) [50, 40, 30, 20, 10] >>>
tuple型 : 定数の配列型
tuple型は、list型と表記が似ているが、処理速度に重点を置いているため、list型に比べ使用メモリが小さくなっている。
その分、同一アドレスでの要素の追加、削除、変更ができないイミュータブルオブジェクトであるため、定数配列とも呼ばれる。
-
型の特性
- イミュータブルオブジェクト
- イテラブルオブジェクト
- シーケンスオブジェクト
-
定義例
要素数が一つの場合を除き、list型とtuple型の定義例の違いは、大カッコ[]であるか小カッコ()であるかの違いのみ。$ python >>> # 変数 tuple_a を空配列で定義 >>> tuple_a = () >>> type(tuple_a) <class 'tuple'> >>> >>> # 変数 tuple_b をコンストラクタを用いて空配列で定義 >>> tuple_b = tuple() >>> type(tuple_b) <class 'tuple'> >>> >>> # 変数 tuple_c を int型の1次元配列で定義 >>> tuple_c = (1, 2, 3, 4, 5) >>> print(tuple_c) (1, 2, 3, 4, 5) >>> type(tuple_c) <class 'tuple'> >>> >>> # 変数 tuple_d を string型の1次元配列で定義 >>> tuple_d = ('a', 'b', 'c', 'd', 'e') >>> type(tuple_d) <class 'tuple'> >>> >>> # 数値と文字列のtuple型 変数 tuple_e を定義 >>> tuple_e = (1, 2, 3, 4, 'five') >>> type(tuple_e) <class 'tuple'> >>> >>> # 変数 tuple_f を string型とint型の2次元配列で定義 >>> tuple_f = ((1, 'one'), (2, 'two')) >>> type(tuple_f) <class 'tuple'> >>> print(tuple_f) ((1, 'one'), (2, 'two')) >>> >>> # (注意)要素数が一つのtuple型の定義は、カンマが必要 >>> tuple_g = (0) # 数値要素が一つでカンマがないとint型の 0として定義される >>> type(tuple_g) <class 'int'> >>> >>> tuple_h = (0,) # 末尾にカンマを付けるとtuple型として定義される >>> type(tuple_h) <class 'tuple'> >>> >>> tuple_i = ('zero') # 文字列要素が一つでカンマがないとstr型の zeroとして定義される >>> type(tuple_i) <class 'str'> >>> >>> tuple_j = ('zero',) # 末尾にカンマを付けるとtuple型として定義される >>> type(tuple_j) <class 'tuple'> >>> >>> tuple_k = 0, # カッコがない状態で末尾にカンマを付けてもtuple型として定義される >>> type(tuple_k) <class 'tuple'> >>> >>> tuple_l = 'zero', >>> type(tuple_l) <class 'tuple'> >>> >>> # 初期値の5を10回繰り返して定義する >>> tuple_m = (5,)*10 >>> type(tuple_m) <class 'tuple'> >>> print(tuple_m) (5, 5, 5, 5, 5, 5, 5, 5, 5, 5) >>> >>> tuple_n = (1, 2, 3) * 5 # 要素が2つ以上ある場合も同様の定義となる >>> print(tuple_n) (1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3) >>>
-
tuple要素の取得
要素の取得も、list型とtuple型の違いは、大カッコ[]であるか小カッコ()であるかの違いのみ。$ python >>> # 変数 tuple_a を string型の1次元配列で定義 >>> tuple_a = ('a', 'b', 'c', 'd', 'e') >>> >>> # 出現回数の取得 >>> tuple_a.count('c') 1 >>> >>> # 1番目を取得 >>> print(tuple_a[0]) a >>> >>> # 4番目(末尾が起点)を取得 >>> print(tuple_a[-2]) d >>> >>> # 1番目から3番目まで取得 >>> print(tuple_a[0:3]) ('a', 'b', 'c') >>> >>> # 先頭(1番目)から最後(5番目)まで取得 >>> print(tuple_a[:]) ('a', 'b', 'c', 'd', 'e') >>> >>> # 3番目から最後(5番目)まで取得 >>> print(tuple_a[2:]) ('c', 'd', 'e') >>> >>> # 4番目(末尾が起点)から最後(5番目)まで取得 >>> print(tuple_a[-2:]) ('d', 'e') >>> >>> # 先頭(1番目)から最後(5番目)まで一つ飛ばしで取得 >>> print(tuple_a[::2]) ('a', 'c', 'e') >>> >>> # tuple内包表記でfor文の結果を取得 >>> tuple_b = (1, 2, 3, 4, 5) >>> tuple([tuple_b_row for tuple_b_row in tuple_b if tuple_b_row > 2]) (3, 4, 5) >>>
-
tuple型要素の追加、変更、削除
tuple型は、イミュータブルオブジェクトであるため要素個別の変更ができない。-
同一アドレス(変数の再定義なし)である場合、追加・変更・削除はすべてエラーになる
$ python >>> tuple_a = (10, 20, 30) >>> id(tuple_a) # idを確認 139970050305480 >>> >>> tuple_a[0] = 11 # id=139970050305480のオブジェクトの1番目を変更 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> >>> del tuple_a[2] # id=139970050305480のオブジェクトの3番目を削除 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object doesn't support item deletion >>>
-
同一アドレスでない場合(変数の再定義する)の追加・変更・削除は、別アドレスで定義されるためエラーにならない
$ python >>> tuple_a = (10, 20, 30) >>> id(tuple_a) # idを確認 139970050305480 >>> >>> tuple_a = (15, 25, 35) # (15, 25, 35)で別アドレスとして再定義(元のオブジェクトは抹消される) >>> print(tuple_a) (15, 25, 35) >>> id(tuple_a) # 上記のidと違う 139970050305840 >>> >>> tuple_a += (45, 55) # (15, 25, 35, 45, 55)で別アドレスとして再定義(元のオブジェクトは抹消される) >>> print(tuple_a) (15, 25, 35, 45, 55) >>> id(tuple_a) # 上記のidと違う 139970050257232 >>> >>> tuple_a = tuple_a + (45, 55, 65) # (15, 25, 35) + (45, 55, 65) で別アドレスとして再定義(元のオブジェクトは抹消される) >>> print(tuple_a) (15, 25, 35, 45, 55, 65) >>> id(tuple_a) # 上記のidと違う 139970072464168 >>>
-
-
その他補足
list型はミュータブルオブジェクトであるため、appendやinsertやremoveなど、様々なメソッドが準備されているが、tuple型はイミュータブルオブジェクトなので、countとindexの\(2\)つだけ。$ python >>> list_a = [1, 2] >>> type(list_a) <class 'list'> >>> dir(list_a) [..., 'append', ..., 'count', ..., 'index', ..., 'remove', ...] >>> >>> tuple_a = (1, 2) >>> type(tuple_a) <class 'tuple'> >>> dir(tuple_a) [..., 'count', 'index', ...] >>>
range型 : 範囲指定
range型は、for文のループ対象など範囲指定を目的としたオブジェクトを作成する。
-
型の特性
- イミュータブルオブジェクト
- イテラブルオブジェクト
- シーケンスオブジェクト
-
定義例
開始位置(デフォルト 0)、終了位置、増加幅(デフォルト\(1\))を指定し定義する。
※ range型のオブジェクト要素を可視化するため、list型に変換した出力をしている。$ python >>> # 開始位置、増加幅を省略(デフォルト適用)し、終了位置のみ指定した定義 >>> range_a = range(5) >>> print(range_a) range(0, 5) >>> type(range_a) <class 'range'> >>> list(range_a) [0, 1, 2, 3, 4] >>> >>> # 開始位置、増加幅を省略(デフォルト適用)し、終了位置をマイナスで定義 >>> range_b = range(-5) >>> print(range_b) range(0, -5) >>> type(range_b) <class 'range'> >>> list(range_b) # 開始位置(デフォルト 0)~終了位置 -5 となるため、区間なしと見なされる [] >>> >>> # 増加幅を省略(デフォルト適用)し、開始位置 5、終了位置 10 を指定した定義 >>> range_c = range(5, 10) >>> print(range_c) range(5, 10) >>> type(range_c) <class 'range'> >>> list(range_c) [5, 6, 7, 8, 9] >>> >>> # 増加幅を省略(デフォルト適用)し、開始位置 -5、終了位置 -10 を指定した定義 >>> range_d = range(-5, -10) >>> print(range_d) range(-5, -10) >>> list(range_d) # 開始位置 -5~終了位置 -10 となるため、区間なしと見なされる [] >>> >>> # 増加幅を省略(デフォルト適用)し、開始位置 -5、終了位置 0 を指定した定義 >>> range_e = range(-5, 0) >>> print(range_e) range(-5, 0) >>> list(range_e) [-5, -4, -3, -2, -1] >>> >>> # 開始位置 1、終了位置 10、増加幅 2 を指定した定義 >>> range_f = range(1, 10, 2) >>> print(range_f) range(1, 10, 2) >>> type(range_f) <class 'range'> >>> list(range_f) [1, 3, 5, 7, 9] >>> >>> # 開始位置 1、終了位置 10、増加幅 -2 を指定した定義 >>> range_g = range(1, 10, -2) >>> print(range_g) range(1, 10, -2) >>> type(range_g) <class 'range'> >>> list(range_g) # 開始位置 1~終了位置 10 と増加しているが、増加幅 -2 なので区間なしと見なされる [] >>> >>> # 開始位置 10、終了位置 1、増加幅 -2 を指定した定義 >>> range_h = range(10, 1, -2) >>> print(range_h) range(10, 1, -2) >>> type(range_h) <class 'range'> >>> list(range_h) [10, 8, 6, 4, 2] >>>
-
float型を指定した定義
range型の生成時、float型は指定できないためリスト内包表記で表現する。$ python >>> # 開始位置 5、終了位置 50、増加幅 5 を指定し、リスト内包表記で10で割る >>> [i / 10 for i in range(5, 50, 5)] [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5] >>>
dict型 : 連想配列型(辞書型)
dict型(辞書型)は、データのキーと値がワンセットになった配列。
※ 多言語のほとんどは、連想配列と呼ばれる。
-
型の特性
- イミュータブルオブジェクト
- イテラブルオブジェクト
- マッピングオブジェクト
-
定義例
$ python >>> # キーと値のセットで定義 >>> dict_a = {'key1': 100, 'key2': 200, 'key3': 300} >>> print(dict_a) {'key1': 100, 'key2': 200, 'key3': 300} >>> type(dict_a) <class 'dict'> >>> >>> # 同じキーを定義した場合、後勝ちで上書かれる >>> # ※エラーにならないので注意。 >>> dict_b = {'key1': 100, 'key2': 200, 'key3': 300, 'key1': 400} >>> print(dict_b) {'key1': 400, 'key2': 200, 'key3': 300} >>> type(dict_b) <class 'dict'> >>> >>> # コンストラクタを使用した定義 >>> dict_c = dict(key1=100, key2=200, key3=300) >>> print(dict_c) {'key1': 100, 'key2': 200, 'key3': 300} >>> type(dict_c) <class 'dict'> >>> >>> # コンストラクタを使用した変換 >>> # ※ list型、tuple型が指定できる >>> dict_d = dict([('key1', 100), ('key2', 200), ('key3', 300)]) >>> dict_d {'key1': 100, 'key2': 200, 'key3': 300} >>> type(dict_d) <class 'dict'> >>>
-
dict要素の取得
$ python >>> dict_a = {'key1': 100, 'key2': 200, 'key3': 300} >>> >>> # すべてのキーを取得 >>> dict_a.keys() dict_keys(['key1', 'key2', 'key3']) >>> >>> # すべての値を取得 >>> dict_a.values() dict_values([100, 200, 300]) >>> >>> # すべてのキーと値を取得 >>> dict_a.items() dict_items([('key1', 100), ('key2', 200), ('key3', 300)]) >>> >>> # キーを指定して値を取得 >>> print(dict_a['key1']) 100 >>>
-
dict要素の追加、変更、削除
$ python >>> dict_a = {'key1': 100, 'key2': 200, 'key3': 300} >>> >>> # キーを指定して追加 >>> dict_a['key4'] = 400 >>> print(dict_a) {'key1': 100, 'key2': 200, 'key3': 300, 'key4': 400} >>> >>> # キーを指定して追加(すでにキーがあれば変更なし) >>> dict_a.setdefault('key5', 500) 500 >>> print(dict_a) {'key1': 100, 'key2': 200, 'key3': 300, 'key4': 400, 'key5': 500} >>> >>> # キーを指定して変更 >>> dict_a['key4'] = 444 >>> print(dict_a) {'key1': 100, 'key2': 200, 'key3': 300, 'key4': 444, 'key5': 500} >>> >>> # キーを指定して削除(pop) >>> dict_a.pop('key4') 444 >>> print(dict_a) {'key1': 100, 'key2': 200, 'key3': 300, 'key5': 500} >>> >>> # キーを指定して削除(del) >>> del dict_a['key3'] >>> print(dict_a) {'key1': 100, 'key2': 200, 'key5': 500} >>>
-
変更時の注意
dict型は代入時、参照渡しするため代入元のdict型に影響を与えたくない場合、copyを使用すること。$ python >>> # copyを使用しない場合 >>> dict_a = {'key1': 100, 'key2': 200, 'key3': 300} >>> >>> dict_a_temp = dict_a >>> dict_a_temp['key2'] = 999 # 代入先のdict型を変更する >>> >>> print(dict_a_temp) {'key1': 100, 'key2': 999, 'key3': 300} >>> print(dict_a) {'key1': 100, 'key2': 999, 'key3': 300} # 代入元のdict型も変更されている >>> >>> # copyを使用した場合 >>> dict_b = {'key1': 100, 'key2': 200, 'key3': 300} >>> >>> dict_b_temp = dict_b.copy() >>> dict_b_temp['key2'] = 999 # 代入先のdict型を変更する >>> >>> print(dict_b_temp) {'key1': 100, 'key2': 999, 'key3': 300} >>> print(dict_b) {'key1': 100, 'key2': 200, 'key3': 300} # 代入元のdict型は変更されていない >>>
-
dict型の結合
str型、list型、tuple型のように**+演算子**で結合ができない。$ python >>> # updateで dict_a に dict_b を追加する(重複キーは後者で上書き) >>> dict_a = {'key1': 100, 'key2': 200, 'key3': 300} >>> dict_b = {'key4': 400, 'key1': 999, 'key2': 999} >>> dict_a.update(dict_b) >>> print(dict_a) {'key1': 999, 'key2': 999, 'key3': 300, 'key4': 400} >>> >>> # updateを使用しない場合 >>> dict_a = {'key1': 100, 'key2': 200, 'key3': 300} >>> dict_b = {'key4': 400, 'key5': 500, 'key6': 600} >>> dict_c = {**dict_a, **dict_b} >>> print(dict_c) {'key1': 100, 'key2': 200, 'key3': 300, 'key4': 400, 'key5': 500, 'key6': 600} >>>