Python tips2 ~ 辞書型

辞書型はあまり意識して学んでこなかったので、ここで一度使い方についてまとめて置こうと思う。

### 辞書型の作り方

```python
# 変数宣言時に初期化
d1 = {'apple': 100, 'orange': 30, 'banana': 50}
# リストを辞書型に変換
l2 = [['strawberry', 400], ['grape', 130], ['melon', 500]]
d2 = dict(l2)
# 2つのリストをzipして辞書型に変換
name = ['apple', 'orange', 'banana']
price = [100, 30, 50]
d3 = dict(zip(name, price))
# 内包表記で初期化
d4 = {n: p*1.08 for n, p in zip(name, price) }
# dict型のコンストラクタで初期化
d5 = dict(apple=100, orange=30, banana=50)
# defaultdictでvalueの初期値としてゼロをセットすることも可能
from collections import defaultdict
d6 = defaultdict(int)
```
 
### 辞書型の追加
```python
d1.update(d2) # >> {'apple': 100,'orange': 30,'banana': 50,'strawberry': 400,'grape': 130,'melon': 500}
```

### 要素の取り出し方
```python
d1['apple'] # >> 100
# 指定したKeyが存在しないとエラーになってしまう
d1['kiwi'] 
  >> NameError: name 'd' is not defined
# get関数を使うと、Keyが無い場合初期値を返す
d1.get('melon) # >> 500
d1.get('kiwi, 0) # >> 0

```

### 要素の追加の仕方
```python
d1['kiwi'] = 200 # >> kiwiを追加
# 既にキーが存在する場合、値が更新されてしまう
d1['apple'] = 350 
# setdefaultを使うと、既にキーが存在する場合は値を更新せず現状の値を返し、無い場合には新規に追加される 
d1.setdefault('apple', 750) 
```

### 要素をまとめて取り出す
```python
d1 = {'a': 1, 'b': 2}
# キーを取り出す
d.keys() # >> ['a', 'b']
# 値を取り出す
d.values() # >> [1, 2]
# キーと値を同時に取り出す
d.items() # >> [('a', 1), ('b', 2)]
# for 文を使って順に取り出す
for key, value in d1.items():
    print('KEY: {},  VALUE: {}'.format(key, value))
#####
# KEY: a,  VALUE: 1
# KEY: b,  VALUE: 2
####
```

### キーの存在確認
```python
d1 = {'apple': 100, 'orange': 30, 'banana': 50}
'apple' in d1 # >> True
'kiwi' in d1 # >> False
```

### 辞書のソート
#### キーでソート
キーでソートする方法は複数ある

```python
d1 = {'apple': 100, 'orange': 30, 'banana': 50, 'strawberry': 400, 'grape': 130, 'melon': 500}
# 辞書型を指定するとデフォルトでキーソートする
sorted(d1)
# keyのリストをlambdaにわたす
sorted(d1.keys(), key=lambda x: x)
# itemsでkey,valueのタプルをlambdaにわたす
s1 = sorted(d1.items(), key=lambda x: x[0])
for k in s:
    print('{}: {}'.format(k, d1.get(k)))
###output
# apple: 100
# banana: 50
# grape: 130
# melon: 500
# orange: 30
# strawberry: 400
###
```

####値でソート
```python
d1 = {'apple': 100, 'orange': 30, 'banana': 50, 'strawberry': 400, 'grape': 130, 'melon': 500}
# valueのリストをlambdaにわたす
sorted(d1.values(), key = lambda v: v)
# key,valueのタプルをlambdaに渡し、添字[1]指定
s = sorted(d1.items(), key=lambda x: x[1])
for k,v in s:
    print('{}: {}'.format(k, v))
### output
# orange: 30
# banana: 50
# apple: 100
# grape: 130
# strawberry: 400
# melon: 500
```

###値でソート (逆順)
```python
d1 = {'apple': 100, 'orange': 30, 'banana': 50, 'strawberry': 400, 'grape': 130, 'melon': 500}
# lambda内の帰り値にマイナス付与することで、大きい数ほど小さくなるようにする
sorted(d1.items(), key=lambda x: -x[1])
# sortedのreverse引数を指定することでも可能
s = sorted(d1.items(), key=lambda x:x[1], reverse=True)
for k,v in s:
    print('{}: {}'.format(k, v))
### output
# melon: 500
# strawberry: 400
# grape: 130
# apple: 100
# banana: 50
# orange: 30
###
```

### 値で逆順にソートし、かつキーでソート
値段の高い順にソートし、値段が同じ場合には文字列順にソートする際に使用

```python
d1 = {'apple': 100, 'orange': 100, 'banana': 100, 'strawberry': 400, 'grape': 130, 'melon': 500}
# 値段の高い順にソート >> 文字列でソート
s1 = sorted(d1.items(), key=lambda x: (-x[1], x[0]))
# 値段の高い順にソート >> 文字列の逆順でソート
s2 = sorted(d1.items(), key=lambda x: (x[1], x[0]), reverse=True)
for k,v in s1:
    print('{}: {}'.format(k, v))
###
# melon: 500
# strawberry: 400
# grape: 130
# apple: 100
# banana: 100
# orange: 100

for k,v in s2:
    print('{}: {}'.format(k, v))
### output
# melon: 500
# strawberry: 400
# grape: 130
# orange: 100
# banana: 100
# apple: 100
###
```