Complex Value Sortとでも呼んでおく(これ何ソート?)
- 指定する辞書のvalueが構造を持つケース
- 複雑な辞書のvalueの中のどこかの値でkey以下の構造をソートする。
- key以下の構造を維持する形でソートする。
- 指定の値が文字列か数値かには注意する。(""やNoneは、事前に弾くか0にでもしておく)
例えば、こんな辞書構造があって
Adic = {
↓こことか ↓ここを軸にソートしたい
'C134':{"price":30,"sales":"1000","profit":200 ,"alist":[110,20,30 ,50]},
'C623':{"price":80,"sales":"100" ,"profit":6 ,"alist":[100,10,30 ,50]},
'C430':{"price":70,"sales":"5000","profit":1000,"alist":[160,11,120,6]},
'C115':{"price":10,"sales":"2400","profit":40 ,"alist":[80 , 1,10 ,6]}
}
ポイントはラムダ式の返り値の表現
sorted()でValue構造内のソートしたい値を指定する(この場合x[1]が内側の辞書型になる)。
key = lambda x: x[1]['profit']
指定したい値がより深い所にある場合たどる必要がある
(x[1]['alist']がリストに相当、その2番目を指定)
key = lambda x: x[1]['alist'][1]
基本はコレ
dic = {'A':10000, 'B':2010, 'C':5, 'D':500}
res = sorted(dic.items(), key=lambda x: x[1]) #value指定
res = sorted(pathD.items(), key=lambda x: int(x[0])) #ちなみにkeyがstrの時のkeyでソート指定
ラムダは関数の略と思えば読める。
def lambda(x): return 2x --> lambda x:2x
dict型は、xに(key,value)タプルが飛び込んでくるので0番か1番か指定している。
import collections
from prettyprint import pp, pp_str #ppはお好みのでどうぞ最近は公式のがあったはず
from collections import OrderedDict
Adic = {
#この4列をvalue内のどこかのvalue値でソートする
'C134':{"price":30,"sales":"1000","profit":200 ,"alist":[110,20,30,50]},
'C623':{"price":80,"sales":"100" ,"profit":6 ,"alist":[100,10,30,50]},
'C430':{"price":70,"sales":"5000","profit":1000,"alist":[160,11,120,6]},
'C115':{"price":10,"sales":"2400","profit":40 ,"alist":[80,1,10,6]}
}
# xには辞書から出てきたタプルが入ってくる感じ。タプルの中をたどってValue指定
# Listで返るので注意
# 全部降順指定:reverse=True
pp('profitでソート')
res1 = sorted(Adic.items(), key=lambda x: x[1]['profit'],reverse=True)
pp(res1)
pp('salesでソート(文字列はintに変換)')
res2 = sorted(Adic.items(), key=lambda x: int(x[1]['sales']),reverse=True)
pp(res2)
pp('alistの2個めでソート')
res3 = sorted(Adic.items(), key=lambda x: x[1]['alist'][1],reverse=True)
pp(res3)
pp('key sort(バックから3つで数字を抜く。3ケタとか固定の場合)')
res4 = sorted(Adic.items(), key=lambda x: int (x[0][-3]) ,reverse=True)#int なくても一応どうにかなる
pp(res4)
pp('key sort(先頭の文字"C"をカット)')
res5 = sorted(Adic.items(), key=lambda x: int(x[0].lstrip('C')) ,reverse=True)
pp(res5)
pp('profitでソート2')
res6 = OrderedDict(sorted(Adic.items(), key=lambda x: x[1]['profit'],reverse=True))
print(res6)#ppだと中で順序がくずれる。
pp(type(res6))
結果
profitのケースだけとりあえず貼ります。
profitの値、1000, 200, 40, 6で降順に構造ごとソートできている!
key的には、c430, c134, c115, c623の構造順になっている。
OrderedDictは、古テクのppと相性が悪い。
"profitでソート"
[
[
"C430",
{
"alist": [
160,
11,
120,
6
],
"price": 70,
"profit": 1000,
"sales": "5000"
}
],
[
"C134",
{
"alist": [
110,
20,
30,
50
],
"price": 30,
"profit": 200,
"sales": "1000"
}
],
[
"C115",
{
"alist": [
80,
1,
10,
6
],
"price": 10,
"profit": 40,
"sales": "2400"
}
],
[
"C623",
{
"alist": [
100,
10,
30,
50
],
"price": 80,
"profit": 6,
"sales": "100"
}
]
]
*最初、python3.5で作ったが、upの際の確認時はpython2.7
*クォート統一してなくてすんません。
#備考
#ラムダ式と関数の関係
def func(x):
return x ** 2
func = lambda x: x ** 2
func(2) #4
#string処理
string.strip()#全部 空白 改行 削除
string.strip("\n\r")#両端でヒットするもの削除
string.rstrip("\n\r")#ケツでヒットするもの削除