ひとり勉強ログ

ITエンジニアの勉強したことメモ

5章 辞書型【退屈なことはPythonにやらせよう】

# 辞書型
my_cat = {'size': 'fat', 'color': 'gray', 'disposition': 'loud'}
print(my_cat['size'])
print('My cat has ' + my_cat['color'] + 'fur.')
# My cat has grayfur.
# 辞書とリストの比較
spam = ['cats', 'dogs', 'moose']
bacon = ['dogs', 'moose', 'cats']
print(spam == bacon)
# False

eggs = {'name': 'Zophie', 'species': 'cat', 'age': '8'}
ham = {'species': 'cat', 'age': '8', 'name': 'Zophie'}
print(eggs==ham)
# True
# 辞書に存在していないキーを使ってアクセスするとKeyErrorというエラーになる
eggs = {'name': 'Zophie', 'age': '7'}
spam['color']
# TypeError: list indices must be integers or slices, not str
birthdays = {'アリス': '4/1', 'ボブ': '12/12', 'キャロル': '4/4'} # 初期の辞書作成
while True:
  print('名前を入力してください:(終了するにはEnterだけ押してください)')
  name = input()
  if name == '':
    break
  
  if name in birthdays: # 入力された名前が辞書のキーとして存在しているかどうかを調べる
    print(name + 'の誕生日は' + birthdays[name])
  else: # 登録されていなければ
    print(name + 'の誕生日は未登録です。')
    print('誕生日を入力してください')
    bday = input()
    birthdays[name] = bday # キー・バリュー・ペアを追加
    print('誕生日データベースを更新しました')
# forループを使って辞書spamを順番にたどる
spam = {'color': 'red', 'age': 42}
for v in spam.values():
  print(v)
# red
# 42

# キーをたどる
for k in spam.keys():
  print(k)
# color
# age

# キー・バリューペアをたどる
for i in spam.items():
  print(i)
# ('color', 'red')
# ('age', 42)

print(spam.keys())
# dict_keys(['color', 'age'])

print(list(spam.keys()))
# ['color', 'age']

# list(spam.keys())ではkeys()から返されたdict_keys型の値をlist()に渡して、['color', 'age']というリストの値を取得している。

# items()メソッドでキーと値を別々の変数に代入したいときは、forループで複数代入の技法を使うことができる。
for k, v in spam.items():
  print('Key: ' + k + ' Value: ' + str(v))
# Key: color Value: red
# Key: age Value: 42
# キーや値が辞書に存在するかどうか判定する
spam = {'name': 'Zophie', 'age': 7}
print('name' in spam.keys())
# True
print('Zophie' in spam.values())
# True
print('color' in spam.keys())
# False
print('color' not in spam.keys())
# True
print('color' in spam)
# False
# get()メソッド
# get()メソッドは、アクセスしたいキーと、そのキーが存在しないときに用いる値の2つの引数をとる。
picnic_items = {'apples': 5, 'cups': 2}
print('I am bringing ' + str(picnic_items.get('cups', 0)) + ' cups.')
# I am bringing 2 cups.
print('I am bringing ' + str(picnic_items.get('eggs', 0)) + ' cups.')
# I am bringing 0 cups.

# getを使わないと以下のようなエラーになる。
print('I am bringing ' + str(picnic_items['eggs']) + ' eggs.')
# KeyError: 'eggs'
# setdefault()メソッド
# 辞書にキーが未登録の場合のみ値を登録したい。
spam = {'name': 'Pooka', 'age': 5}
if 'color' not in spam:
  spam['color'] = 'black'

# setdefault()というメソッドを用いると、1行で書くことができる
# 第1引数には調べたい器w−指定し、第2引数にはそのキーが存在しない時にい設定する値を指定する。
spam = {'name': 'Pooka', 'age': 5}
print(spam.setdefault('color', 'black'))
# black
print(spam)
# {'name': 'Pooka', 'age': 5, 'color': 'black'}
print(spam.setdefault('color', 'white'))
# black
print(spam)
# {'name': 'Pooka', 'age': 5, 'color': 'black'}

# 最初にdetdefault()メソッドを呼び出すと、辞書spamは{'name': 'Pooka', 'age': 5, 'color': 'black'}となる。このとき'color'というキーの値として'black'が設定されたので、メソッドは'black'を返す。次にspam.setdefault('white')を呼び出すと、キー'color'は登録済なので、値は'white'にはならない。
message = 'It was a bright cold day in April, and the clocks were striking thirteen.'
count = {}

for character in message:
  count.setdefault(character, 0)
  count[character] = count[character] + 1

print(count)
# {'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 4, 'A': 1, 'p': 1, ',': 1, 'e': 5, 'k': 2, '.': 1}
# pprintモジュールをインポートすると、辞書の内容をきれいに表示するpprint()やpformat()関数を使うことができる。
import pprint

message = 'It was a bright cold day in April, and the clocks were striking thirteen.'

for character in message:
  count.setdefault(character, 0)
  count[character] = count[character] + 1

pprint.pprint(count)
# {' ': 26,
#  ',': 2,
#  '.': 2,
#  'A': 2,
#  'I': 2,
#  'a': 8,
#  'b': 2,
#  'c': 6,
#  'd': 6,
#  'e': 10,
#  'g': 4,
#  'h': 6,
#  'i': 12,
#  'k': 4,
#  'l': 6,
#  'n': 8,
#  'o': 4,
#  'p': 2,
#  'r': 10,
#  's': 6,
#  't': 12,
#  'w': 4,
#  'y': 2}
# 三目並べのボードを表現するデータ構造
the_board = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
             'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
             'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

# プレイヤーXが先手で中央のマスを選ぶ
the_board = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
             'mid-L': ' ', 'mid-M': 'X', 'mid-R': ' ',
             'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

# プレイヤーOが上のラインに「O」を揃えて勝った状態
the_board = {'top-L': 'O', 'top-M': 'O', 'top-R': 'O',
             'mid-L': 'X', 'mid-M': 'X', 'mid-R': ' ',
             'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

# 画面に表示する関数
the_board = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
             'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
             'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

def print_board(board):
  print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
  print('-+-+-')
  print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
  print('-+-+-')
  print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])

print_board(the_board)
#  | | 
# -+-+-
#  | | 
# -+-+-
#  | | 

the_board = {'top-L': 'O', 'top-M': 'O', 'top-R': 'O',
             'mid-L': 'X', 'mid-M': 'X', 'mid-R': ' ',
             'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

print_board(the_board)
# O|O|O
# -+-+-
# X|X| 
# -+-+-
#  | | 
# プレイヤーに駒の動きを入力してもらうコード
the_board = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
             'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
             'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

def print_board(board):
  print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
  print('-+-+-')
  print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
  print('-+-+-')
  print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])

turn = 'X'
for i in range(9):
  print_board(the_board)
  print(turn + 'の番です。どこに打つ?')
  move = input()
  the_board[move] = turn
  if turn == 'X':
    turn = 'O'
  else:
    turn = 'X'

print_board(the_board)
# 辞書とリストの入れ子
all_guests = {'アリス': {'リンゴ': 5, 'プレッツェル': 12},
             'ボブ': {'ハムサンド': 3, 'りんご': 2},
             'キャロル': {'コップ': 3, 'アップルパイ': 1}}

def total_brought(guests, item):
  num_brought = 0
  for k, v in guests.items():
    num_brought = num_brought + v.get(item, 0)
  return num_brought

print('持ち物の数:')
print(' - リンゴ' + str(total_brought(all_guests, 'リンゴ')))
print(' - コップ' + str(total_brought(all_guests, 'コップ')))
print(' - ケーキ' + str(total_brought(all_guests, 'ケーキ')))
print(' - ハムサンド' + str(total_brought(all_guests, 'ハムサンド')))
print(' - アップルパイ' + str(total_brought(all_guests, 'アップルパイ')))

#  - リンゴ5
#  - コップ3
#  - ケーキ0
#  - ハムサンド3
#  - アップルパイ1