Python编程快速上手-让繁琐工作自动化 — 读书与代码笔记

chapter5

# -*- coding:utf-8 -*-
# @FileName     :chapter5_dictionary_structural_data.py
# @Time         :2020/8/15 14:51
# @Author       :Wu Hongyi
# @Copyright    :Wu Hongyi
# Function description:
'''
本文件为Python编程快速上手-让繁琐工作自动化一书的第五章示例练习代码

'''
# @version      :Version1.0
# Modification description:
'''

'''

# 字典数据类型
# 字典索引可用许多不同数据类型,不只是整数,其索引被称为‘键’,‘键’及其关联值称为‘键值对’
mycat = {'size': 'fat', 'color': 'gray', 'disposition': 'loud'}
mycat['size']
'My cat has ' + mycat['color'] + ' fur.'

# 字典仍然可以用整数值作为键,就像列表使用整数值作为下标一样,但它们不必从0开始,可以是任何数字
spam = {12345: 'Luggage Combination', 42: 'The Answer'}

# 字典与列表
# 字典中没有“第一个”表项。虽然确定两个列表是否相同时,表项的顺序很重要,但在字典中,键-值对输入的顺序并不重要
spam = ['cats', 'dogs', 'moose']
bacon = ['dogs', 'moose', 'cats']
spam == bacon
eggs = {'name': 'Zophie', 'species': 'cats', 'age': '8'}
ham = {'species': 'cats', 'age': '8', 'name': 'Zophie'}
eggs == ham


# 用字典来保存生日信息数据的程序
# birthdays.py
birthdays = {'Alice': 'Apr 1', 'Bob': 'Dec 12', 'Carol': 'Mar 4'}
while True:
    print('Enter a name:(blank to quit)')
    name = input()
    if name == '':
        break

    if name in birthdays:
        print(birthdays[name] + ' is the birthday of ' + name)
    else:
        print('I do not have birthday information for ' + name)
        print('What is their birthday?')
        bday = input()
        birthdays[name] = bday
        print('Birthday database upgrade.')
# 创建了一个初始的字典,将它保存在birthdays中。用in关键字,可以看看输入的名字是否作为键存在于
# 字典中,就像查看列表一样。如果该名字在字典中,你可以用方括号访问关联的值。如果不在,你可以用同
# 样的方括号语法和赋值操作符添加它

# keys()、values()和items()方法
# 以上3个字典方法将返回类似列表的值,分别对应于字典的键、值和键值对。
# 这些方法返回的值不是真正的列表,不能被修改,没有append()方法
# 但这些数据类型(dict_keys、dict_values和dict_items)可以用于for循环
spam = {'color': 'red', 'age': 42}
for v in spam.values():
    print(v)
# 这里,for循环迭代了spam字典中的每个值。for循环也可以迭代每个键,或者键-值对
for k in spam.keys():
    print(k)
for i in spam.items():
    print(i)
# items()方法返回的dict_items值中,包含的是键和值的元组

# 若希望通过这些方法得到一个真正的列表,就把类似列表的返回值传递给list函数
list(spam.keys())
# 也可以利用多重赋值的技巧,在for循环中将键和值赋给不同的变量
spam = {'color': 'red', 'age': 42}
for k, v in spam.items():
    print('Key: ' + k + ' Value: ' + str(v))

# 检查字典中是否存在键或值
# 可以使用in或not in检查某个键或值是否存在于字典中。
spam = {'name': 'Zophie', 'age': 7}
'name' in spam.keys()
'Zophie' in spam.values()
'Color' in spam.keys()
'color' not in spam.keys()
'color' in spam

'name' in spam
7 in spam
# 注意:,'color' in spam本质上是一个简写版本。相当于'color' inspam.keys()。
# 这种情况总是对的:如果要检查一个值是否为字典中的键,就可以用关键字in(或not in),作用于该字典本身。

# get()方法
# 在访问一个键的值之前,检查该键是否存在于字典中,这很麻烦。好在,字典有一个get()方法,它有两个参数:
# 要取得其值的键,以及如果该键不存在时,返回的备用值。
picnicItems = {'apples': 5, 'cups': 2}
'I am bringing ' + str(picnicItems.get('cups', 0)) + ' cups.'
'I am bringing ' + str(picnicItems.get('eggs', 0)) + ' eggs.'
# 因为picnicItems字典中没有'egg'键,get()方法返回的默认值是0。不􀖯用get(),代码就会产生一个错误消息
'I am bringing ' + str(picnicItems['eggs']) + ' eggs.'

# setdefault()方法
# 我们常常需要为字典中某个键设置一个默认值,当该键没有任何值时使用它
spam = {'name': 'Pooka', 'age': 5}
if 'color' not in spam:
    spam['color'] = 'black'
spam['color']
# setdefault()方法提供了一种方式,在一行中完成这件事。传递给该方法的第一个参数,是要检查的键。
# 第二个参数,是如果该键不存在时要设置的值。如果该键确实存在,方法就会返回键的值
spam = {'name': 'Pooka', 'age': 5}
spam.setdefault('color', 'black')
spam.setdefault('name', 'miki')
# setdefault()方法是一个很好的快捷方式,可以确保一个键存在

##### 非常实用
# 小程序:,计算一个字符串中每个字符出现的次数。
# characterCounter.py
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)
# setdefault()方法调用确保了键存在于count字典中(默认值是0),这样在执行
# count[character] = count[character] + 1
# 时,就不会􁣋出KeyError错误

# 漂亮打印
# 如果程序中导入pprint模块,就可以使用pprint()和pformat()函数,它们将“漂亮打印”一个字典的字。
# 如果想要字典中表项的显示比print()的输出结果更干净,这就有用了。
import pprint
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
pprint.pprint(count)
# 如果字典本身包含嵌套的列表或字典,pprint.pprint()函数就特别有用
# 如果希望得到漂亮打印的文本作为字符串,而不是显示在屏幕上,那就调用pprint.pformat()。
# 法1:
pprint.pprint(someDictionaryValue)
# 法2:
print(pprint.pformat(someDictionaryValue))
# 以上两语句效果相同
spam = {'name': 'Pooka', 'age': 5}
print(pprint.pformat(spam))

# 使用数据结构对真实世界建模
# 井字棋游戏模拟
# 井字棋盘看起来像一个大的井字符号(#),有9个空格,可以包含X、O或空。要用字典表示棋盘
# 可以为每个空格分配一个字符串键
# 可以用字符串值来表示,棋盘上每个空格有什么:'X'、'O'或' '(空格字符)。因此,需要存储
# 9个字符串。可以用一个字典来做这事。带有键'top-R'的字符串表示右上角,带有键'low-L'的字
# 符串表示左下角,带有键'mid-M'的字符串表示中间,以此类推。这个字典就是表示井字棋盘的数据结构
theBoard = {
    'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
    'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
    'low-L': ' ', 'low-M': ' ', 'low-R': ' '
}
# 一个玩家O获胜的棋盘上,他将O横贯棋盘的顶部,看起来像这样:
theBoard = {'top-L': 'O', 'top-M': 'O', 'top-R': 'O',
            'mid-L': 'X', 'mid-M': 'X', 'mid-R': ' ',
            'low-L': ' ', 'low-M': ' ', 'low-R': 'X'}

# ticTacToe.py
theBoard = {
    'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
    'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
    'low-L': ' ', 'low-M': ' ', 'low-R': ' '
}

def printBoard(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'])
printBoard(theBoard)
# printBoard()函数可以处理传入的任何井字棋数据结构
theBoard = {'top-L': 'O', 'top-M': 'O', 'top-R': 'O',
            'mid-L': 'X', 'mid-M': 'X', 'mid-R': ' ',
            'low-L': ' ', 'low-M': ' ', 'low-R': 'X'}
def printBoard(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'])
printBoard(theBoard)
# 因为创建了一个数据结构来表示井字棋盘,编写了printBoard()中的代码来解释该数据结构
# 所以就有了一个程序,对井字棋盘进行了“建模”。也可以用不同的方式组织数据结构(比如,
# 使用'TOP-LEFT'这样的键来代替'top-L'),但只要代码能处理你的数据结构,就有了正确
# 工作的程序。printBoard()函数预期井字棋数据结构是一个字典,包含所有9个空格的键。假
# 如传入的字典缺少'mid-L'键,程序就不能工作了。

# 添加代码,允许玩家输入他们的招法
theBoard = {
    'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
    'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
    'low-L': ' ', 'low-M': ' ', 'low-R': ' '
}

def printBoard(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):
    printBoard(theBoard)
    print('Turn for ' + turn + '. Move on which space?')
    move = input()
    theBoard[move] = turn
    if turn == 'X':
        turn = 'O'
    else:
        turn = 'X'
printBoard(theBoard)
# 以上程序不完整(如没有错误输入检查,也无获胜检查)完整的井字棋程序的源代码在网上有介绍
# 网址是http://nostarch.com/automatestuff/

# 嵌套的字典和列表
# 对复杂的事物建模时,可能发现字典和列表中需要包含其他字典和列表。列表适用于包含一组有序的值,
# 字典适合于包含关联的键与值
allGuests = {
    'Alice': {'apples': 5, 'pretzels': 12},
    'Bob': {'ham sandwiches': 3, 'apples': 2},
    'Carol': {'cups': 3, 'apple pies': 1}
    }
def totalBrought(guests, item):
    numBrought = 0
    for k, v in guests.items():
        numBrought = numBrought + v.get(item, 0)
    return numBrought
print('Number of things being brought:')
print(' - Apples ' + str(totalBrought(allGuests, 'apples')))
print(' - Cups ' + str(totalBrought(allGuests, 'cups')))
print(' - Cakes ' + str(totalBrought(allGuests, 'cakes')))
print(' - Ham Sandwiches ' + str(totalBrought(allGuests, 'ham sandwiches')))
print(' - Apple Pies ' + str(totalBrought(allGuests, 'apple pies')))
# 在这个循环里,客人的名字字符串赋给k,他们带来的野餐食物的字典赋给v。如果食物参数是字典中存在的键,它的值
# (数量)就添加到numBrought,如果它不是键,get()方法就返回0,添加到numBrought。

# 这个函数totalBrought()可以轻易地处理一个字典,其中包含数千名客人,每个人都带来了“数千种”不同的
# 野餐食物。这样用这种数据结构来保存信息,并用totalBrought()函数,就会节约大量的时间!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值