読者です 読者をやめる 読者になる 読者になる

22時に寝ようと思って2時に寝る。

備忘録や日記を書いてます。きょうは早く寝よう。

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時点の全国気温観測値ランキングを手打ちした。

f:id:azuuun:20150501114518p:plain

手打ちかよ…という感じだけど、 まだ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

python OrderedDict便利だが注意が必要 | Shannon Lab

Pythonでコレクション型をソート - Qiita