head first python(第六章)–学习笔记

样例数据

Sarah Sweeney,2002-6-17,2:58,2.58,2:39,2-25,2-55,2:54,2.18,2:55,2:55,2:22,2-21,2.22

需要将数据整理,实现人名+出生日期+成绩的输出

以往的做法是:

def sanitize(time_string):
    if '-' in time_string:
        splitter = '-'
    elif ':' in time_string:
        splitter = ':'
    else:
        return(time_string)
    (mins, secs) = time_string.split(splitter)
    return(mins + '.' + secs)

def get_coach_data(filename):
    try:
        with open(filename) as f:
            data = f.readline()
        return(data.strip().split(','))
    except IOError as ioerr:
        print('File error: ' + str(ioerr))
        return(None)
    
sarah = get_coach_data('sarah2.txt')

(sarah_name, sarah_dob) = sarah.pop(0), sarah.pop(0)

print(sarah_name + "'s fastest times are: " +
        str(sorted(set([sanitize(t) for t in sarah]))[0:3]))

这次加入了字典的做法

字典将数据值与键关联:

key   -->   value
Name        "sarah sweeney"
DOB         "2002-6-17"
Times       "[2:58,2.58,2:39,2-25,2-55,2:54,2.18,2:55,2:55,2:22,2-21,2.22]"

创建字典的方式可以是

cleese = {} #大括号!!

也可以是

palin = dict()

关联key和value的话是

cleese['Name'] = 'John Cleese'  # 一个key 对应一个字符串

或者

cleese['Name'] = ['John Cleese','John Cleese1','John Cleese2','John Cleese3','John Cleese4'] #一个key对应一个list

或者

cleese = {'Name':'abc','Address':'asdasdasda'}  #注意是用冒号

另外数据值与key关联后,需要访问数据值里面的某个数据项的话,可以是

cleese['Name'][-1] 

类似多维数组使用。

代码改为

#!/usr/bin/python
# -*- coding: utf-8 -*-


def sanitize(time_string):
        if '-' in time_string:
                splitter = '-'
        elif ':' in time_string:
                splitter = ':'
        else:
                return(time_string)
        (mins,secs) = time_string.split(splitter)
        return (mins + '.' + secs)

def get_coach_data(filename):
        try:
                with open(filename) as f:
                        data = f.readline()
                return(data.strip().split(','))
        except IOError as ioerr:
                print('File error:' + str(ioerr))
                return(None)

sarah = get_coach_data('sarah2.txt')

sarah_data={}
sarah_data['Name'] = sarah.pop(0)   #根据数据结构,第一个数据是名字,第二个是生日,第二个之后是成绩,所以分别将相关数据赋值到字典里面。
sarah_data['DOB'] = sarah.pop(0)
sarah_data['Times'] = sarah

print(sarah_data['Name'] + "'s fastest times are: " + str(sorted(set([sanitize(t) for t in sarah_data['Times']]))[0:3]))

字典的方法优势在于合理使用数据结构。是否知道何时使用列表而何时使用字典,这正式从好的程序员中区分出优秀程序员的一个标准。
字典其实也叫“映射”,“散列”,“关联数组”

为了更加方便的处理多个人的成绩的数据,所以将字典数据转移到函数里面去,直接通过函数生成出字典,并返回需要的数据

#!/usr/bin/python
# -*- coding: utf-8 -*-


def sanitize(time_string):
        if '-' in time_string:
                splitter = '-'
        elif ':' in time_string:
                splitter = ':'
        else:
                return(time_string)
        (mins,secs) = time_string.split(splitter)
        return (mins + '.' + secs)

def get_coach_data(filename):
        try:
                with open(filename) as f:
                        data = f.readline()
                templ = data.strip().split(',')
                return({'Name':templ.pop(0),    #这里就是字典
                        'DOB':templ.pop(0),
                        'Times':str(sorted(set([sanitize(t) for t in templ]))[0:3])})
        except IOError as ioerr:
                print('File error:' + str(ioerr))
                return(None)

sarah = get_coach_data('sarah2.txt')
james = get_coach_data('james2.txt')

print(sarah['Name'] + "'s fastest times are: " + sarah['Times'])

这就是将代码和数据打包在一起。特定函数应用特定数据。

更加正规的做法是建立类。

类是面向对象oop编程模型的东西,类的概念在这里不详细描述。

类可以

1.降低复杂性
2.方便维护和扩展

python的类需要有一个self参数,这个参数是用来标识是属于哪个对象实例的

例如:

class Athlete:
    def __init__(self,value=0):
        self.thing = value      #定义这个类的属性thing
    def how_big(self)           #定义一个方法how_big
        return(len(self.thing))

btw:init 是类的python固定实现方法,所以是必须的。

你写的代码                   -->     python执行的代码
d = Athlete("Holy Grail")           Athlete.__init__(d,"Holy Grail")
                                    |         |      |  
                                    类       方法    目标标识符 
                                    |         |     |
d.how_big()                         Athlete.how_big(d)

代码改为:

def sanitize(time_string):
    if '-' in time_string:
        splitter = '-'
    elif ':' in time_string:
        splitter = ':'
    else:
        return(time_string)
    (mins, secs) = time_string.split(splitter)
    return(mins + '.' + secs)

class Athlete:
    def __init__(self, a_name, a_dob=None, a_times=[]):
        self.name = a_name      #通过类的属性来定义name,dob和times
        self.dob = a_dob
        self.times = a_times
        
    def top3(self):
        return(sorted(set([sanitize(t) for t in self.times]))[0:3])
        
def get_coach_data(filename):
    try:
        with open(filename) as f:
            data = f.readline()
        templ = data.strip().split(',')
        return(Athlete(templ.pop(0), templ.pop(0), templ))
    except IOError as ioerr:
        print('File error: ' + str(ioerr))
        return(None)
    
james = get_coach_data('james2.txt')
julie = get_coach_data('julie2.txt')
mikey = get_coach_data('mikey2.txt')
sarah = get_coach_data('sarah2.txt')

print(james.name + "'s fastest times are: " + str(james.top3()))
print(julie.name + "'s fastest times are: " + str(julie.top3()))
print(mikey.name + "'s fastest times are: " + str(mikey.top3()))
print(sarah.name + "'s fastest times are: " + str(sarah.top3()))

科普:

1.通过在各个对象的属性中保留原始数据,可以支持类扩展来满足将来的其他需求。如果处理数据并作为对象初始化代码的一部分,说明你已对程序员将如何使用这个类做出了假设,而日后这些假设肯定会对你造成障碍。

在类里面增加一个灵活的增加成绩数据的函数

可以是增加单个成绩,或是增加多个成绩
单个成绩用add_time,传入的是字符串
多个成绩是add_times,传入的是list

以下是单个成绩的样例:

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Athlete:
        def __init__(self,a_name,a_dob=None,a_times=[]):
                self.name = a_name
                self.dob = a_dob
                self.times = a_times

        def add_time(self,time_value):      #这里就是了。
                self.times.append(time_value)
        def top3(self):
                return (sorted(set([sanitize(t) for t in self.times]))[0:15])
        def add_times(self,list_of_times):
                self.times.extend(list_of_times)

def sanitize(time_string):
        if '-' in time_string:
                splitter = '-'
        elif ':' in time_string:
                splitter = ':'
        else:
                return(time_string)
        (mins,secs) = time_string.split(splitter)
        return (mins + '.' + secs)

def get_coach_data(filename):
        try:
                with open(filename) as f:
                        data = f.readline()
                templ = data.strip().split(',')
                return (Athlete(templ.pop(0),templ.pop(0),templ))
        except IOError as ioerr:
                print('File error:' + str(ioerr))
                return(None)

sarah = get_coach_data('sarah2.txt')

sarah.add_time('2.88')      #这里调用
print(sarah.name + "'s fastest times are: " + str(sarah.top3()))    #输出结果会改变

观察到这个类有点像list,所以有重复制造车轮的嫌疑,并且功能单一,所以决定集成list类

def sanitize(time_string):
    if '-' in time_string:
        splitter = '-'
    elif ':' in time_string:
        splitter = ':'
    else:
        return(time_string)
    (mins, secs) = time_string.split(splitter)
    return(mins + '.' + secs)

class AthleteList(list):    #继续list类,所以这里要写list的名字

    def __init__(self, a_name, a_dob=None, a_times=[]):
        list.__init__([])   #这里需要初始化list类
        self.name = a_name
        self.dob = a_dob
        self.extend(a_times)    #因为集成list类了,所以这里可以直接使用list的extend方法

    def top3(self):
        return(sorted(set([sanitize(t) for t in self]))[0:3])
        
def get_coach_data(filename):
    try:
        with open(filename) as f:
            data = f.readline()
        templ = data.strip().split(',')
        return(AthleteList(templ.pop(0), templ.pop(0), templ))
    except IOError as ioerr:
        print('File error: ' + str(ioerr))
        return(None)
    
james = get_coach_data('james2.txt')
julie = get_coach_data('julie2.txt')
mikey = get_coach_data('mikey2.txt')
sarah = get_coach_data('sarah2.txt')

print(james.name + "'s fastest times are: " + str(james.top3()))
print(julie.name + "'s fastest times are: " + str(julie.top3()))
print(mikey.name + "'s fastest times are: " + str(mikey.top3()))
print(sarah.name + "'s fastest times are: " + str(sarah.top3()))

原文引用:http://www.godblessyuan.com/2015/05/03/head_first_python_chapter_6_learning/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 19,025评论 17 410
  • 人生苦短我用 Python 注:最后附电子书地址 一、Pythonic Thinking 第1条: 确认自己所用的...
    molscar阅读 2,046评论 0 3
  • 2016年5月24日 星期三 大雨 今天,我们满怀着希望来到学校,因为我们把足球比赛踢到了决赛。我们的三班比二...
    仔哥阅读 262评论 0 0
  • 一、觉察 亲爱的自己:你好,你知道吗?现在你正处于心情愉悦中,早上送完孩子和老婆一起去湿地公园里挖野菜。 二、...
    孙兰昌阅读 210评论 0 0
  • 相遇是一种缘分更是一场修行。 在艳阳吝啬,阴雨霏霏的今秋,注定又有一场与新生修...
    繁华过往阅读 581评论 0 2