PythonのOrderedDictの使い方
Pythonの標準の辞書(dict)は挿入した順番が記憶されず維持できない。
辞書(dict)については僕のもう一つの備忘録ブログ"ざっくりん雑記"のほうで確認済みです。 "ざっくりん雑記"ではこちらより適当にプログラミング関係の備忘録を書いてまとめてます。
azuuun-memorandum.hatenablog.com
以下で復習も兼ねて確認してみる。
- コード
# --- coding: utf-8 --- testNomalDict = {'one':1, 'two':2, 'three':3, 'four':4, 'five':5} for key,val in testNomalDict.iteritems(): print "%s %d" %(key,val)
結果はこうなる。挿入した順序には出力できない模様。
- 結果
four 4 three 3 five 5 two 2 one 1
挿入した順序を記憶し維持してほしい時は、標準ライブラリの collections.OrderedDict() を使えば順番を保持した辞書を作れる。
8.3. collections — 高性能なコンテナ・データ型 — Python 2.7ja1 documentation
OrderedDictの使い方
使い方は標準の辞書(dict)とほとんど変わらないが、書き方は「追加」しているように書く。
- コード
# --- coding: utf-8 --- from collections import OrderedDict testOrderedDict = OrderedDict() testOrderedDict['one'] = 1 testOrderedDict['two'] = 2 testOrderedDict['three'] = 3 testOrderedDict['four'] = 4 testOrderedDict['five'] = 5 for key,val in testOrderedDict.iteritems(): print "%s %d" %(key,val)
結果は順序が維持されている。
- 結果
one 1 two 2 three 3 four 4 five 5
もっと簡単に書けないの?
タプルしたものをOrderedDictにして、testOrderedDictにupdateしてみる。
- コード
add = (('six', 6),('seven', 7),('eight', 8),('nine', 9),('ten', 10)) newDict = OrderedDict(add) testOrderedDict.update(newDict) for key,val in testOrderedDict.iteritems(): print "%s %d" %(key,val)
結果、できた。
- 結果
one 1 two 2 three 3 four 4 five 5 six 6 seven 7 eight 8 nine 9 ten 10
ソート(sort)してOrderedDictに入れる
標準の辞書だとsortしたものを入れても順序が維持されないけど、OrderedDictなら大丈夫。
やってみる。ソートするのに何かデータが欲しかったので2015/5/1 9:10時点の全国気温観測値ランキングを手打ちした。
手打ちかよ…という感じだけど、 まだAPI諸々使えないので…。いつか引っ張ってこれるようになろう。
- コード
# --- coding: utf-8 --- from collections import OrderedDict # 2015/5/1 9:10時点の全国気温観測値ランキングTOP10(わざとソートを崩した) airTempValue = {'Nakasuji,Okinawa':24.4, 'Shitaabaru,Okinawa': 25.8, 'Hateruma,Okinawa': 25.0, 'Kuji,Iwate':25.7, 'Moriyama,Okinawa':24.9, 'Ohara,Okinawa':24.4, 'Yonagunijima,Okinawa':24.9, 'Taneichi,Iwate':24.6, 'Ishigakijima':25.1, 'Tokorono,Okinawa':24.9} airTempRanking = OrderedDict(sorted(airTempValue.items(), key = lambda x:x[1], reverse=True)) for key,val in airTempRanking.iteritems(): print "%s %.1f" %(key,val)
- 結果
Shitaabaru,Okinawa 25.8 Kuji,Iwate 25.7 Ishigakijima 25.1 Hateruma,Okinawa 25.0 Tokorono,Okinawa 24.9 Yonagunijima,Okinawa 24.9 Moriyama,Okinawa 24.9 Taneichi,Iwate 24.6 Nakasuji,Okinawa 24.4 Ohara,Okinawa 24.4
いい感じにソートされました。ただ少し、見づらい。
PrettyTableを使ってASCIIテーブルで表示してみる
ASCIIテーブルで出力したいなと思ったので探すと、ドンピシャなものを見つけた。
Python の PrettyTable でプリティーな ASCII テーブルを作る | CUBE SUGAR STORAGE
早速、pipでインストールして、使ってみた。
- コード
# --- coding: utf-8 --- from collections import OrderedDict from prettytable import PrettyTable # 2015/5/1 9:10時点の全国気温観測値ランキングTOP10(わざとソートを崩した) airTempValue = {'Nakasuji,Okinawa':24.4, 'Shitaabaru,Okinawa': 25.8, 'Hateruma,Okinawa': 25.0, 'Kuji,Iwate':25.7, 'Moriyama,Okinawa':24.9, 'Ohara,Okinawa':24.4, 'Yonagunijima,Okinawa':24.9, 'Taneichi,Iwate':24.6, 'Ishigakijima':25.1, 'Tokorono,Okinawa':24.9} airTempRanking = OrderedDict(sorted(airTempValue.items(), key = lambda x:x[1], reverse=True)) table = PrettyTable() table.add_column('City', airTempRanking.keys()) table.add_column('AirTemperature', airTempRanking.values()) table.padding_width = 2 table.align['City'] = 'l' print table
- 結果
+------------------------+------------------+ | City | AirTemperature | +------------------------+------------------+ | Shitaabaru,Okinawa | 25.8 | | Kuji,Iwate | 25.7 | | Ishigakijima | 25.1 | | Hateruma,Okinawa | 25.0 | | Tokorono,Okinawa | 24.9 | | Yonagunijima,Okinawa | 24.9 | | Moriyama,Okinawa | 24.9 | | Taneichi,Iwate | 24.6 | | Nakasuji,Okinawa | 24.4 | | Ohara,Okinawa | 24.4 | +------------------------+------------------+
うまくできた! 非常にPrettyなASCIIテーブルです。
keysの要素を','でスライスして、CityとPrefectureという別々のリストにして3列のテーブルにしたかったんだけど、 方法がいまいち分からず断念。今後の課題に。 そもそも、地名と気温の数値を辞書型で管理するのがベストなのかな。どうなんだろ。あうあうあ~。
追記
keysの要素のスライス、出来ました。
azuuun-memorandum.hatenablog.com
参考
Pythonの辞書で順番を保つにはOrderedDictを使う - minus9d's diary