アウトプット用です。
とある問題集を解いて私が苦手だと思った部分を紹介します。
sorted & lambda関数
これは第三位ですね
例題 以下の辞書のValueを降順にソートするプログラムを作成
※使用する辞書 :
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
▼期待する出力
Valueでソートした辞書 : {'C': 444, 'D': 333, 'B': 222, 'A': 111}
ソートってことはsorted(d)
だよね!
って最初は思ってたんですが、これだとキーでソートしてしまうんですよ...
ってことで結論の回答です。
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
d2 = sorted(d.items(), key=lambda x:x[1], reverse=True)
print(f"Valueでソートした辞書{dict(d2)}")
# 実行結果
Valueでソートした辞書{'C': 444, 'D': 333, 'B': 222, 'A': 111}
ここのミソはsortedの引数3つです
①d.items()
これによってキーと値の両方を取得しています。
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
d2 = sorted(d.items())
print(f"キーと値の両方をソート\n{d2}")
# 実行結果
キーと値の両方をソート
[('A', 111), ('B', 222), ('C', 444), ('D', 333)]
②key, lambda
これによってキーではなく値でソート可能
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
d2 = sorted(d.items(), key=lambda x:x[1])
print(f"値でソート\n{d2}")
# 実行結果
値でソート
[('A', 111), ('B', 222), ('D', 333), ('C', 444)]
そして第二引数で使われているlambdaです。
これは無名関数と言われており簡単な処理の関数を引数として持ってくる際に使うことが多いです。
解説は以下です。
def func(引数):
return 戻り値
# ↓lambda関数化↓
lambda 引数: 戻り値
# 例で使われている部分
lambda x:x[1]
今回は渡された要素の2番目の要素である値を返す無名関数となっています。
③reverse
第三引数でreverse=True
とすることで
降順にすることができます。
リストのスライス
これは第二位ですね
例題 以下のリストでインデックス番号が奇数の要素だけを出力するプログラムを2行で作成
※使用するリスト :
l = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
▼期待する出力
偶数のインデックス番号 : ['B', 'D', 'F', 'H', 'J']
2行というのにビックリ
for文+if文を複数行書いて実行することはできません。
結論、以下が答えです。
l = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
print(f"偶数のインデックス番号:{l[1::2]}")
# 実行結果
偶数のインデックス番号:['B', 'D', 'F', 'H', 'J']
簡単に表すとstart:stop:step
という表し方です。
何回も解いて慣れることが一番です。
以下が一例です。
num_list = list(range(10))
# 全て
print(num_list) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 先頭から5つ
print(num_list[:5]) # [0, 1, 2, 3, 4]
# 末尾から5つ
print(num_list[5:]) # [5, 6, 7, 8, 9]
print(num_list[-5:]) # [5, 6, 7, 8, 9]
# 先頭から偶数のインデックス番号
print(num_list[0::2]) # [0, 2, 4, 6, 8]
# 末尾から奇数のインデックス番号
print(num_list[::-2]) # [9, 7, 5, 3, 1]
リスト内包表記
これが第一位で一番厄介でした。例題と一緒に解説します。
例題 以下の二次元リストを一次元にするプログラムを3行以下で作成
※使用するリスト:
l = [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]]
▼期待する出力
一次元にしたリスト:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
l = [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]]
new_l = [x for n in l for x in n]
print(f"一次元にしたリスト:{new_l}")
# 実行結果
一次元にしたリスト:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
初めて解説を見た時は驚きました。
この場合の順序は上の画像のようになります。
- 赤のfor文
- 青のfor文
- 黄色のxをxに格納
これを略さず書くと以下のようになります。
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
new_l = []
# 外側のループ: l の各要素(内側のリスト)を順番に取り出す
for n in l:
# 内側のループ: n(内側のリスト)の各要素を順番に取り出す
for x in n:
# 取り出した要素xをnew_lに追加する
new_l.append(x)
print(f"一次元にしたリスト:{new_l}")
# 実行結果
一次元にしたリスト:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
こっちの方がわかりやすい!
確かにぱっと見はそうかもしれません。
ただ、リスト内包表記には処理時間が短いというメリットがあるのです。また、コードが短くて済むので簡潔になります。