Python リストとタプルの使い方
はじめに
連続した複数の要素を扱う際に利用するリストと、リストと似たような用途で利用されるタプルついて、基本的な使い方をサンプルコードを用いて説明します。
データ型
リストとタプルは連続した複数の要素を取り扱うことができるデータ型です。
厳密には、これらはシーケンス型と呼ばれるデータ型に含まれています。
リストの使い方
記述方法
リストの記述方法は以下の通りです。リストの値を要素と呼びます。
- [](角かっこ)でくくる
- 各要素をカンマで区切る
fruits= ['apple', 'banana', 'orange', 'grape'] # リストの作成
初期化
以下のように要素を含まない角かっこを指定するとリストを初期化できます。
この状態ではsample
は要素を持たない空リストの状態です。
sample = [] # 空リストの作成
要素の取得
単一の要素を取得
リストの各要素はインデックスを指定することで取得できます。
インデックスは0から始まります。
pythonでは負のインデックスを指定することもできます。
- 1がリストの末尾を表し、-2, -3のように数値を小さくしていくことで末尾から2番目、3番目のように指定できます。
fruits = ['apple', 'banana', 'orange', 'grape'] print('[0]', fruits[0]) # 0番目の要素を取得 print('[2]', fruits[2]) # 2番目の要素を取得 print('[-1]', fruits[-1]) # 末尾(3番目)の要素を取得 print('[-3]', fruits[-3]) # 末尾から3番目の要素を取得
[0] apple [2] orange [-1] grape [-3] banana
複製の要素をまとめて取得
スライスを利用するとリストから複数の要素をまとめて取得できます。スライスの評価結果は新規リストです。
スライスは2つの整数値を[1:3]
のように[開始インデックス:終了インデックス+1]
のように指定します。
2つめの数値はそのインデックス自身は含まれず、1つ小さいインデックスの要素が含まれます。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits[1:3]) # 1,2番目の要素を取得 print(fruits[:2]) # 0,1番目の要素を取得 print(fruits[2:]) # 2番目から末尾までの要素を取得 print(fruits[2:-1]) # 2番目から末尾-1番目までの要素を取得
['banana', 'orange'] ['apple', 'banana'] ['orange', 'grape'] ['orange']
リストの長さの取得
リストの長さを取得するにはlen()
関数を利用します。
fruits = ['apple', 'banana', 'orange', 'grape'] print(len(fruits)) # リストの長さを取得
4
リストの操作
要素の変更
要素を変更するには、変更したい要素のインデックスを指定します。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits) # 初期化後のリストを表示 fruits[1] = 'lemon' print(fruits) # 要素変更後のリストを表示
['apple', 'banana', 'orange', 'grape'] ['apple', 'lemon', 'orange', 'grape']
要素の追加
要素を末尾に追加するにはappend()
メソッドを利用します。
要素を挿入するにはinsert()
メソッドを利用します。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits) # 初期化後のリストを表示 fruits.append('lemon') print(fruits) # 要素追加後のリストを表示 fruits.insert(1, 'melon') print(fruits) # 要素挿入後のリストを表示
['apple', 'banana', 'orange', 'grape'] ['apple', 'banana', 'orange', 'grape', 'lemon'] ['apple', 'melon', 'banana', 'orange', 'grape', 'lemon']
append()
メソッド、insert()
メソッドはリストそのものを変更します。関数の戻り値はNoneです。
None値については、以下の記事で説明しています。
akuruhinode.hatenablog.com
要素の削除
要素の値を指定して削除するにはremove()
メソッドを利用します。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits) # 初期化後のリストを表示 fruits.remove('orange') print(fruits) # 削除後のリストを表示
['apple', 'banana', 'orange', 'grape'] ['apple', 'banana', 'grape']
インデックスを指定して削除するにはdel
文を利用します。この例では、remove('orange')
と同じ結果が得られます。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits) # 初期化後のリストを表示 del fruits[2] print(fruits) # 削除後のリストを表示
remove()
メソッドはリストそのものを変更します。関数の戻り値はNoneです。
要素の検索
index()
メソッドを利用することで、ある要素がリストに含まれているかを検索できます。要素が含まれている場合は、そのインデックスを返します。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits.index('orange')) # 'orange'のインデックスを表示
2
指定した値がリストに含まれていない場合はValueError例外を発生させます。
ほかのプログラミング言語にも似た関数はありますが、検索対象が見つからない場合は-1を返すことが多いと思います。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits.index('lemon')) # 'lemon'(リストに存在しない値)のインデックスを表示
Traceback (most recent call last): File "sample.py", line 2, in <module> print(fruits.index('lemon')) ValueError: 'lemon' is not in list
単純にある要素がリストにあるかどうかだけを知りたい場合は、in
演算子、not in
演算子を利用できます。
in
演算子を利用することで、リストに含まれるかを評価できます。
not in
演算子を利用することで、リストに含まれていないかを評価できます。
これらは'orange' in fruits
のように検索対象 in リスト
の形で利用できますが、if文と合わせて利用することが多いと思います。
fruits = ['apple', 'banana', 'orange', 'grape'] if 'orange' in fruits: # 'orange'を含む場合True print('orangeを含む') else: print('orangeを含まない') if 'lemon' not in fruits: # 'lemon'を含まない場合True print('lemonを含まない') else: print('lemonを含む')
orangeを含む lemonを含まない
リストの連結
数学演算子の+演算子を利用することで、複数のリストを連結できます。
fruits = ['apple', 'banana', 'orange', 'grape'] vegetables = ['tomato', 'pumpkin'] foods = fruits + vegetables print(fruits) # 1つめのリストを表示 print(vegetables) # 2つめのリストを表示 print(foods) # 1つめのリストと2つめのリストの連結結果を表示
['apple', 'banana', 'orange', 'grape'] ['tomato', 'pumpkin'] ['apple', 'banana', 'orange', 'grape', 'tomato', 'pumpkin']
この+演算子では異なるデータ型を含むリストも連結できます。
リストの複製
リストは参照渡しされますので、別の変数に代入しても代入先のリストで要素を変更すると元のリストの要素も変わってしまいます。
fruits = ['apple', 'banana', 'orange', 'grape'] fruits_copy = fruits fruits_copy[1] = 'lemon' print(fruits) # 要素の変更後のリストを表示(copy元) print(fruits_copy) # 要素の変更後のリストを表示(copy先)
['apple', 'lemon', 'orange', 'grape'] ['apple', 'lemon', 'orange', 'grape']
元のリストの要素を変更せずリストを複製したい場合は、copyモジュールのcopy()
関数を利用します。
import copy fruits = ['apple', 'banana', 'orange', 'grape'] fruits_copy = copy.copy(fruits) fruits_copy[1] = 'lemon' print(fruits) # 要素の変更後のリストを表示(copy元) print(fruits_copy) # 要素の変更後のリストを表示(copy先)
['apple', 'banana', 'orange', 'grape'] ['apple', 'lemon', 'orange', 'grape']
copy()
関数ではリストにリストが含まれていると内部のリストが参照渡しされてしまうため正しく複製されません。その場合はdeepcopy()
関数を利用します。copy()
関数とdeepcopy()
関数の違いについては、以下の記事で説明しています。
akuruhinode.hatenablog.com
リストの要素の複製
あるリストを別のリストに複製するのではなくリスト内の要素自体を複製する場合は、*演算子を利用できます。
fruits = ['apple', 'banana', 'orange', 'grape'] print(fruits) # 初期化後のリストを表示 fruits = fruits*2 print(fruits) # 要素の複製後リストを表示
['apple', 'banana', 'orange', 'grape'] ['apple', 'banana', 'orange', 'grape', 'apple', 'banana', 'orange', 'grape']
ソート
sort()
メソッドを利用すると、リストをソートできます。
sort(reverse=True)
と指定すると、逆順にソートします。
fruits= ['apple', 'banana', 'orange', 'grape'] print(fruits) # 初期化後のリストを表示 fruits.sort() print(fruits) # 昇順ソート後のリストを表示 fruits.sort(reverse=True) print(fruits) # 逆順ソート後のリストを表示
['apple', 'banana', 'orange', 'grape'] ['apple', 'banana', 'grape', 'orange'] ['orange', 'grape', 'banana', 'apple']
リストに異なる型の要素を含むとソートできません。
その他の使い方
forループとの組み合わせ
forループを組み合わせることで、リストの値を順番に取得できます。forループとの組み合わせ方は2通りあります。
for 変数名 in リスト:
とすることで、リストの要素が順番に変数に格納されます。
for 変数名 in range(len(リスト)):
とすることで、リストのインデックスが順番に変数に格納されます。
fruits = ['apple', 'banana', 'orange', 'grape'] for fruit in fruits: # 要素を順番に取得 print(fruit) print('---') for i in range(len(fruits)): # インデックスを順番に取得 print(fruits[i])
apple banana orange grape --- apple banana orange grape
異なる型を同一のリストに含める
リストには異なる型の要素を含めることができます。
fruits = ['apple', 1, -1.2, ['banana', 'orange']] for i in range(len(fruits)): print(str(i) + ' ' + str(type(fruits[i]))) # 要素の型を表示
0 <class 'str'> 1 <class 'int'> 2 <class 'float'> 3 <class 'list'>
異なる型を含むリストで
sort()
メソッドを利用すると、TypeErrorが発生します。タプルの使い方
リストとの違い
タプルはリストと似ていますが、以下が異なります。
- ()(丸かっこ)でくくる
- 要素を変更できない
それ以外はリストと同じです。以下のリストの使い方と同じように利用できます。サンプルコードの角かっこを丸かっこに置き換えてください。
- 初期化
- 要素の取得
- リストの操作 ※タプルの操作
- その他の使い方
- forループとの組み合わせ
- 異なる型を同一のリストに含める ※異なる型を同一のタプルに含める
以下では、type()
メソッドを利用して型が異なることを確認しています。
fruits = ['apple', 'banana', 'orange', 'grape'] fruits_tuple=('apple', 'banana', 'orange', 'grape') print(type(fruits)) #type()でリストの型を表示 print(type(fruits_tuple)) #type()でタプルの型を表示
<class 'list'> <class 'tuple'>
リストのように途中で要素を変更することはできませんので、以下のようなコードはTypeErrorのエラーが発生します。
fruits = ('apple', 'banana', 'orange', 'grape') # 以下はすべてエラーになる fruits[1] = 'lemon' fruits.append('lemon') fruits.insert(1, 'melon') fruits.remove('orange') del fruits[2]
ミュータブルとイミュータブル
リストのように途中で要素を変更できる型をミュータブル(変更可能)といい、タプルのように途中で要素を変更できない型をイミュータブル(変更不可)といいます。
リストとタプルの変換
list()
関数とtuple()
関数を利用することで、リスト、タプルを相互変換できます。それぞれ以下のように利用します。
変換後のタプル = tuple(変換するリスト) 変換後のリスト = list(変換するタプル)
リストとタプルの違いは、かっこの違いを除けばミュータブル(変更可能)か、イミュータブル(変更不可)かだけでした。そのため、それぞれ簡単に相互変換できます。
fruits = ['apple', 'banana', 'orange', 'grape'] fruits_tuple = tuple(fruits) # リストからタプルに変換 fruits_list = list(fruits) # タプルからリストに変換 print(type(fruits_tuple)) # リストからタプルへの変換後の型を表示 print(type(fruits_list)) # リストからタプルへの変換後の型を表示
<class 'tuple'> <class 'list'>