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

ざっくりん雑記

プログラミングで忘れそうなことをひたすらメモる

Python - 辞書(dict)のkeysをリストにしてsplitした話

備忘録 python

今日はサークルがありました。

ドットインストールの

dotinstall.com

に沿って、先輩方が丁寧に解説して教えてくれるという活動内容。ありがとうございます!

このPython入門は個人的には既に一周してるけど、二周目でも普通にやりごたえがある。たぶん一周目、寝ながらやってたんだ。眠いときって集中力以前に文章読んでも内容を全く理解できなかったりする。理解できなくて半分寝てることに気づいて「あぁ、やばいやばい…」と前項まで戻って読み返すみたいなね…。素直に寝ろって感じだ。(だいたい夜の23時あたりにこんな状態になってる)

そろそろ本題へ。

辞書のkeysをリスト化してsplitした

先日、メインブログの方でOrderedDictの使い方に関して備忘録を書いた。

azunobu.hatenablog.com

どんなプログラムを書いたかというと、

  • ある日の全国最高気温ランキングのデータを手打ちして辞書に入れた
  • 普通の辞書じゃ順序を記憶しないけどOrderedDictは記憶してくれるから気温の高い順にソート処理した(ランキングの高い順に格納)
  • そのまま出力しても見づらいのでPrettyTableを使ってASCIIテーブルを作って出力した

こんな感じ。

  • 出力したASCIIテーブル
+------------------------+------------------+
|  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       |
+------------------------+------------------+

Cityの要素はOrderedDictのkeysの要素で、AirTemperatureがvaluesの要素。

さらに「Shitaabaru,Okinawa」をsplitを使って ['Shitaabaru', 'Okinawa'] のように市町村と都道府県で別々のリストに分割したかった。 色々試したんだけど方法が分からずその日は諦めた。

それで、今日色々いじってたらできたので残しておく。

結果を書くとこんな感じ。本当にざっくり。

  • コード
# 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,Okinawa':25.1, 'Tokorono,Okinawa':24.9}

airTempRanking = OrderedDict(sorted(airTempValue.items(), key = lambda x:x[1], reverse=True))

tempCityPref = airTempRanking.keys()

City = []
Pref = []
for address in tempCityPref:
    tmpList = address.split(",")
    City.append(tmpList[0])
    Pref.append(tmpList[1])
    del tmpList[:]

# ASCII TABLE CREATE

rank = range(1,11)

table = PrettyTable()
table.add_column('Rank', rank)
table.add_column('Pref', Pref)
table.add_column('City', City)
table.add_column('AirTemperature', airTempRanking.values())
table.padding_width = 2
table.align['City'] = 'l'
table.align['Pref'] = 'l'
print table
  • 結果
+--------+-----------+----------------+------------------+
|  Rank  |  Pref     |  City          |  AirTemperature  |
+--------+-----------+----------------+------------------+
|   1    |  Okinawa  |  Shitaabaru    |       25.8       |
|   2    |  Iwate    |  Kuji          |       25.7       |
|   3    |  Okinawa  |  Ishigakijima  |       25.1       |
|   4    |  Okinawa  |  Hateruma      |       25.0       |
|   5    |  Okinawa  |  Tokorono      |       24.9       |
|   6    |  Okinawa  |  Yonagunijima  |       24.9       |
|   7    |  Okinawa  |  Moriyama      |       24.9       |
|   8    |  Iwate    |  Taneichi      |       24.6       |
|   9    |  Okinawa  |  Nakasuji      |       24.4       |
|   10   |  Okinawa  |  Ohara         |       24.4       |
+--------+-----------+----------------+------------------+

辞書(dict)のkeysをリストにしてsplitする方法

上の例だと説明しづらいので新たに辞書を作ってみる。valuesの値でソートは今回はしません。

user_info = {'Tanaka,male': 1000, 'Yoshida,female': 1200,'Satou,male': 1500} 

keysには名前と性別、valueは何かのスコアだとする。

user_name_sex = user_info.keys()

keysだけ取り出してみる。

この時点で'user_name_sex'は

  • どういう属性になってるか
  • 内容はどんな感じか

確認してみる

print type(user_name_sex)
print user_name_sex
<type 'list'>
['Satou,male', 'Yoshida,female', 'Tanaka,male']

'user_name_sex'は既にリストだった。変換とかいらないんだ。

  • 辞書名.keys()で渡される要素は勝手にリストになる

当たり前か。keys()だけ取ってるのにまた辞書になるわけがないか…。

次に、

  • ['Satou,male', 'Yoshida,female', 'Tanaka,male'] を
    • nameリスト ['Satou', 'Yoshida', 'Tanaka']
    • sexリスト ['male', 'female', 'male']

の2つにsplitを使って分割(スライス)する。

name = []
sex = []
for user in user_name_sex:
    tmpList = user.split(",")
    name.append(tmpList[0])
    sex.append(tmpList[1])
    del tmpList[:]

文章で説明しづらいので、所々でprintしてみる。

name = []
sex = []
for user in user_name_sex: # ........(1)
    print user
    tmpList = user.split(",") # .....(2)
    print tmpList
    name.append(tmpList[0]) # .......(3)
    print name
    sex.append(tmpList[1]) # ........(4)
    print sex
    del tmpList[:] # ................(5)
    print tmpList
(1) Yoshida,female
(2) ['Yoshida', 'female']
(3) ['Yoshida']
(4) ['female']
(5) []
(1) Satou,male
(2) ['Satou', 'male']
(3) ['Yoshida', 'Satou']
(4) ['female', 'male']
(5) []
(1) Tanaka,male
(2) ['Tanaka', 'male']
(3) ['Yoshida', 'Satou', 'Tanaka']
(4) ['female', 'male', 'male']
(5) []

こんな流れです。

最後に、これをPrettyTableで出力すると、

+-----------+----------+---------+
|    NAME   |   SEX    |  SCORE  |
+-----------+----------+---------+
|  Yoshida  |  female  |   1200  |
|   Satou   |   male   |   1500  |
|   Tanaka  |   male   |   1000  |
+-----------+----------+---------+

こんな感じになります。

  • 全体のコード
# coding: utf-8

from prettytable import PrettyTable

user_info = {'Tanaka,male': 1000, 'Yoshida,female': 1200,'Satou,male': 1500} 

user_name_sex = user_info.keys()

name = []
sex = []
for user in user_name_sex:
    tmpList = user.split(",")
    name.append(tmpList[0])
    sex.append(tmpList[1])
    del tmpList[:]
    

# ASCII TABLE CREATE

table = PrettyTable()
table.add_column('NAME', name)
table.add_column('SEX', sex)
table.add_column('SCORE', user_info.values())
table.padding_width = 2
table.align['NAME'] = 'l'
print table

余談

ここ3日くらいPythonの辞書ばっかりやってる気がする。

正直、天気のランキング情報やユーザ情報をこんな感じで管理するのは正しいのかわからない! きっとデータベース使うんだろうな!知らんけど!MySQL勉強してみようかな?

辞書オブジェクトがどんな用途で活躍しているのかが分からないので、今後いろんなPythonソースコードを読んでみるとわかってくるかな?