V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
xuweitiger
V2EX  ›  Python

关于 python 中的字典的一点疑问,请各位大神帮忙解答

  •  
  •   xuweitiger · 2016-09-14 10:51:13 +08:00 · 2442 次点击
    这是一个创建于 3027 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小弟是菜鸡一枚,最近在学习 python ,按着《 Head_First_Python 》中的样例代码一点一点的写,在写到 Chapter 7 的时候遇到一点疑惑,烦请各位大神解答.

    问题描述: 这是一个记录运动员姓名,出生日期,以及每次训练成绩的问题, 需要处理的文本文件的格式是酱紫的:

    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

    这是其中的一个文件,里面记录的运动员的姓名,出生日期,以及每次训练的成绩(时间),类似的文件总共有四个。

    我的问题是,在最后输出阶段, data 是经过程序处理返回的一个字典,里面的 key 是姓名, value 是运动成绩,但是为何可以通过

    data[each_athlete].dob
    

    这种方式调用到出生日期呢? 按理说 data 不应该只包含运动员的姓名和成绩吗?

    以下是代码:

    先是定义了一个类:

    class AthleteList(list):
        def __init__(self,a_name,a_dob=None,a_times=[]):
            list.__init__([])
            self.name = a_name
            self.dob = a_dob
            self.extend(a_times)
    

    然后引用这个类:

    import pickle
    from athletelist import AthleteList
    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)
            
    def put_to_store(files_list):
        all_athletes = {}
        for each_file in files_list:
            ath = get_coach_data(each_file)
            all_athletes[ath.name] = ath
        try:
            with open('athletes.pickle','wb') as athf:
                pickle.dump(all_athletes,athf)
        except IOError as ioerr:
            print('File error (put_and_store):' + str(ioerr))
        return(all_athletes)
    
    def get_from_store():
        all_athletes = {}
        try:
            with open('athletes.pickle','rb') as athf:
                all_athletes = pickle.load(athf)
        except IOError as ioerr:
            print('File error(get_from_store):' + str(ioerr))
        return(all_athletes)
    

    然后是输出:

    print('-----------------第一段输出------------------------')
    
    the_files = ['sarah2.txt','james2.txt','mikey2.txt','julie2.txt']
    data = put_to_store(the_files)
    print(data)
    

    第一段输出的结果:

    {'Julie Jones': ['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21', '3.01', '3.02', '2:59'], 'James Lee': ['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22', '2-01', '2.01', '2:16'], 'Sarah Sweeney': ['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55', '2:22', '2-21', '2.22'], 'Mikey McManus': ['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38', '2:40', '2.22', '2-31']}
    
    print('-----------------第二段输出------------------------')
    
    for each_athlete in data:
        print(data[each_athlete].name + ' ' + data[each_athlete].dob)
    

    第二段输出结果:

    Julie Jones 2002-8-17
    James Lee 2002-3-14
    Sarah Sweeney 2002-6-17
    Mikey McManus 2002-2-24
    
    
    print('------------------第三段输出-------------------------')
    
    data_copy = get_from_store()
    for each_athlete in data_copy:
        print(data_copy[each_athlete].name + ' ' + data_copy[each_athlete].dob)
    

    第三段输出的结果:

    Julie Jones 2002-8-17
    Sarah Sweeney 2002-6-17
    James Lee 2002-3-14
    Mikey McManus 2002-2-24
    
    
    8 条回复    2016-09-14 14:46:10 +08:00
    xuweitiger
        1
    xuweitiger  
    OP
       2016-09-14 11:09:40 +08:00
    请各位大哥大姐帮忙解答,多谢
    aiver
        2
    aiver  
       2016-09-14 11:13:52 +08:00
    首先, AthleteList 类里面定义了三个字段: name , dob 和成绩 list , dob 字段就是出生日期。然后在 get_coach_data 函数进行 data 填充时把“ 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 ”格式数据的第二个字段即“ 2002-6-17 ”填充到了 AthleteList 的 dob 字段,返回的是一个以 name 为键, AthleteList 实例为值的字典,所以在输出时可以通过 name 键找到相应的 AthleteList 实例,实例里面自然可以通过 dob 字段来访问到出生日期了。
    xuweitiger
        3
    xuweitiger  
    OP
       2016-09-14 11:23:37 +08:00
    @aiver 那为何在第一段输出时,直接 print ( data )的时候,输出结果中没有 dob 呢?
    lcc4376
        4
    lcc4376  
       2016-09-14 11:24:48 +08:00   ❤️ 1
    def get_coach_data(filename):
    裡 templ = data.strip().split(',')
    return(AthleteList(templ.pop(0),templ.pop(0),templ)) <-----第二個 templ.pop(0)就是 dob 了
    lcc4376
        5
    lcc4376  
       2016-09-14 11:26:20 +08:00
    @xuweitiger 第一段並沒有用 get_coach_data 去 split(',')
    lxy
        6
    lxy  
       2016-09-14 11:50:54 +08:00   ❤️ 1
    AthleteList 继承了 list ,做了一点改造。 data 是个字典,字典 value 是 AthleteList 对象。 print 的时候好像默认调用对象的__str__ 函数,而 AthleteList 并没有改写该函数,所以调用的是它的父类 list 的 __str__,打印的即 self.extend(a_times) 中加入的内容。
    aiver
        7
    aiver  
       2016-09-14 12:32:09 +08:00   ❤️ 1
    @xuweitiger 这个其实你要看 AthleteList 的定义,它只是继承了 list 但并未重写 list 中的方法, print 输出默认是调用输出类型的__str__内置函数,因为 AthleteList 并未重新__str__函数,所以调用的父类 list 的__str__函数, list 的__str__输出就是它自身的内容,对于 AthleteList 就是输出 self.extend()中的内容。如果按照完整的输出的话,其实第一部分应该输出内容如下:{'Julie Jones':{'name':'Julie Jones', 'dob':'2002-6-17', ['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21', '3.01', '3.02', '2:59'],}, {...}}。
    xuweitiger
        8
    xuweitiger  
    OP
       2016-09-14 14:46:10 +08:00
    @aiver
    @lcc4376
    @lxy
    感谢三位大神回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2838 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 07:35 · PVG 15:35 · LAX 23:35 · JFK 02:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.