Pythonのリスト(配列)の特定の要素を抽出、置換、変換
Pythonで、既存のリスト(配列)の特定の条件を満たす要素のみを抽出・削除したり置換や変換などの処理をしたりして新たなリストを生成するには、リスト内包表記を使う。
本記事のサンプルコードでは以下のリストを例とする。
l = list(range(-5, 6))
print(l)
# [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
文字列のリストについての具体例は以下の記事を参照。
条件を満たす要素ではなく、ランダムに抽出することも可能。
なお、リストは異なる型のデータを格納可能で、厳密には配列とは異なる。配列を扱いたい場合はarray(標準ライブラリ)やNumPyを使う。
リスト内包表記の基本的な形
リストから新たなリストを生成する場合はリスト内包表記を使うとforループよりもシンプルに書ける。
[式 for 任意の変数名 in イテラブルオブジェクト if 条件式]
イテラブルオブジェクト
(リストやタプルなど)の条件式
を満たす要素に式
が適用され、新たなリストの要素となる。if 条件式
は省略可能で、省略した場合はすべての要素に式
が適用される。
ネストしたリスト内包表記など、詳しくは以下の記事を参照。
- 関連記事: Pythonリスト内包表記の使い方
リストの要素すべてに処理を適用
例えばリストの要素すべてに何らかの処理を適用したい場合は、上述のリスト内包表記の式
に所望の処理を記述する。
l_square = [i**2 for i in l]
print(l_square)
# [25, 16, 9, 4, 1, 0, 1, 4, 9, 16, 25]
l_str = [str(i) for i in l]
print(l_str)
# ['-5', '-4', '-3', '-2', '-1', '0', '1', '2', '3', '4', '5']
これを利用すると、数値のリストと文字列のリストを変換したりできる。詳細は以下の記事を参照。
リストから条件を満たす要素を抽出・削除
要素を条件式
で選択するだけであれば式
で処理することはないので、
[変数名 for 変数名 in 元のリスト if 条件式]
という形になる。
条件を満たす要素(条件式
がTrue
となる要素)のみが抽出された新たなリストが生成される。
l_even = [i for i in l if i % 2 == 0]
print(l_even)
# [-4, -2, 0, 2, 4]
l_minus = [i for i in l if i < 0]
print(l_minus)
# [-5, -4, -3, -2, -1]
if 条件式
をif not 条件式
にすると否定になり、条件を満たさない要素(条件式
がFalse
となる要素)のみを選択して抽出、つまり、条件を満たす要素が削除された新たなリストが生成される。
l_odd = [i for i in l if not i % 2 == 0]
print(l_odd)
# [-5, -3, -1, 1, 3, 5]
l_plus = [i for i in l if not i < 0]
print(l_plus)
# [0, 1, 2, 3, 4, 5]
もちろん、not
を使わずに相当の条件式を指定しても同じ結果となる。
l_odd = [i for i in l if i % 2 != 0]
print(l_odd)
# [-5, -3, -1, 1, 3, 5]
l_plus = [i for i in l if i >= 0]
print(l_plus)
# [0, 1, 2, 3, 4, 5]
条件式
の部分は複数条件にすることもできる。複数の条件式をor
やand
でつなげればよい。否定not
も使える。
l_minus_or_even = [i for i in l if (i < 0) or (i % 2 == 0)]
print(l_minus_or_even)
# [-5, -4, -3, -2, -1, 0, 2, 4]
l_minus_and_odd = [i for i in l if (i < 0) and not (i % 2 == 0)]
print(l_minus_and_odd)
# [-5, -3, -1]
リストの条件を満たす要素を置換・変換
上述の要素の抽出の例では、条件を満たさない要素が取り除かれた。
条件を満たさない要素はそのままで条件を満たす要素に対して置換や変換などの処理を行いたい場合は、リスト内包表記の式
の部分に三項演算子を適用する。
Pythonでは三項演算子は以下のように書ける。
真の値 if 条件式 else 偽の値
a = 80
x = 100 if a > 50 else 0
print(x)
# 100
b = 30
y = 100 if b > 50 else 0
print(y)
# 0
ちょっとややこしいが、リスト内包表記と三項演算子を組み合わせると以下のようになる。
[真の値 if 条件式 else 偽の値 for 任意の変数名 in 元のリスト]
カッコで囲んだ部分が三項演算子(実際のコードではカッコは必要ない)。
[(真の値 if 条件式 else 偽の値) for 任意の変数名 in 元のリスト]
真の値
や偽の値
に任意の変数名
をそのまま書けば元の要素の値がそのまま使われるし、何らかの式を書けばその式の処理が適用される。
l_replace = [100 if i > 0 else i for i in l]
print(l_replace)
# [-5, -4, -3, -2, -1, 0, 100, 100, 100, 100, 100]
l_replace2 = [100 if i > 0 else 0 for i in l]
print(l_replace2)
# [0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100]
l_convert = [i * 10 if i % 2 == 0 else i for i in l]
print(l_convert)
# [-5, -40, -3, -20, -1, 0, 1, 20, 3, 40, 5]
l_convert2 = [i * 10 if i % 2 == 0 else i / 10 for i in l]
print(l_convert2)
# [-0.5, -40, -0.3, -20, -0.1, 0, 0.1, 20, 0.3, 40, 0.5]