こんにちは、sanagiです!
突然ですが、私はエンジニアとして働くようになって、実務ではPythonを使うことが多かったのですが、未経験の頃はJavaでプログラミングを勉強していました。
Pythonを使うようになってから、こんな書き方ができるんだ!と思うことも良くあったので、私が個人的に便利だなぁと感じたPythonの記述を紹介していきたいと思います。
ちなみに、実行環境はpaiza.ioの「Python3」で実行しています。
https://paiza.io/ja
簡単に試したいときにブラウザで動作確認できるので、インストールする必要がなく便利です!
内包表記
まずは内包表記です。これはよく使われますね。実際にやってみた方が分かりやすいので、やってみましょう!
以下の配列データを使ってやってみます。
# 元のリストデータ
fruits = [
{
'name': 'orange',
'color': 'orange'
},
{
'name': 'apple',
'color': 'red'
},
{
'name': 'strawberry',
'color': 'red'
}
]
①シンプルにfor文で取得した要素を返す形
まずは一番簡単な形です。
こんな感じで1行でfor文の要素を取り出し、配列化させることができます。これが内包表記といわれるものです。
# nameのみを取り出しリスト化
fruit_names = [fruit["name"] for fruit in fruits]
print(fruit_names) # ['orange', 'apple', 'strawberry']
②内包表記内で条件分岐
次はリスト内で条件分岐をつけるパターンです。
ifのみの場合とif,elseで分けられる場合と両方1行で書くことができます。
# ①ifのみの分岐
# colorがredの要素のみ取得しnameを返す
red_fruits = [fruit['name'] for fruit in fruits if fruit['color'] == 'red']
print(red_fruits) # ['apple', 'strawberry']
# ②if, elseの分岐
# colorがredの場合とそうでない場合で分岐
red_fruits2 = [
fruit['name'] if fruit['color'] == 'red' else '赤色ではないfruit' for fruit in fruits
]
print(red_fruits2) # ['赤色ではないfruit', 'apple', 'strawberry']
ifのみの場合はfor~の後ろに、if, elseの場合はfor~の前半に持ってきます。
内包表記の利点は、すっきり短く書けることはもちろんなのですが、処理時間が普通のfor文で回すより速くなることです。ただし、複雑な処理になる場合はfor文の方が可読性が良い場合もあるので、そこは使い分けると良いかな?と思います。
最後におまけですが、enumerateを使うことで、インデックスを返すこともできます。
# enumerateを使い、インデックス値とnameを返す
fruit_names2 = [(i, fruit['name']) for i, fruit in enumerate(fruits)]
print(fruit_names2) # [(0, 'orange'), (1, 'apple'), (2, 'strawberry')]
zip関数
zip関数は、複数のイテラブル(リスト、タプル、文字列など)を同時に処理できる便利な関数です。早速紹介していきます。
①複数のリストを同時にループ
zip関数を使い、複数の配列データを以下のように同時に取り出すことができます。
例は通常のfor文で書きましたが、もちろん内包表記とも組み合わせて使えます。
# 元データ(テストの成績情報)
names = ['yamada', 'tanaka', 'sato'] # 生徒の名前
ages = [12, 13, 11] # 生徒の年齢
scores = [93, 97, 89] # テストの点数結果
for name, age, score in zip(names, ages, scores):
print(name, age, score)
# yamada 12 93
# tanaka 13 97
# sato 11 89
②2つのリストを辞書化
以下のように、keyとvalueのリストをzipに渡すことで、dictに変換することができます。
# 元データ(テストの成績情報)
# keyのリスト
keys = ['name', 'age', 'score']
# テストの成績情報のリスト
score_infos = [['yamada', 12, 93], ['tanaka', 13, 97], ['sato', 11, 89]]
# keysとscore_infosを組み合わせてdictを生成
score_dicts = [dict(zip(keys, info)) for info in score_infos]
print(score_dicts)
# [{'name': 'yamada', 'age': 12, 'score': 93}, {'name': 'tanaka', 'age': 13, 'score': 97}, {'name': 'sato', 'age': 11, 'score': 89}]
③(ちょっと応用)sorted関数と組み合わせて並び替え
sortedの引数は以下のような意味合いになります。
・zip(names, scores)⇒zip(names, scores)が並び替えの対象
・key=lambda x: x[1]と指定⇒name, scoreのうちscoreの点数でなら並び替えることを指定
・reverse=True⇒降順
# 元データ(テストの成績情報)
names = ['yamada', 'tanaka', 'sato'] # 生徒の名前
scores = [93, 97, 89] # テストの点数結果
# keysとscore_infosを組み合わせてdictを生成
for name, score in sorted(zip(names, scores), key=lambda x: x[1], reverse=True):
print(f'{name}: {score}')
# tanaka: 97
# yamada: 93
# sato: 89
おわりに
どうでしたか?
個人的に、こういった便利な書き方は何となく覚えておくと、調べたらすぐに出てくるので、何となくあれあったなぁ、、くらいには覚えておくとよい気がします。
ただ複雑な処理の場合は、逆に短く書こうとすると可読性が悪くなるので、そこは気をつけたいところですね。
他にも便利な関数や書き方色々あると思うので、使ってみてまた紹介できたらなと思います。