RWPy4learner 11.3.30 documentation

Version: 11.3.30
[首页] 更加简化的通信录 << 再次优化通信录 (Source) >>推荐阅读

再次优化通信录

小白不断地在他的 list 中添加新的联系人,可是很快,他就发现随着联系人的增加,他的 list 越来越大。“哇靠,这么大的 list ,俺眼都花了!”。小白添加到了第 49 个同学的信息时,再也无法忍受这庞大的 list。“卧槽!这么大的通信录,而且联系人还是一个连着一个的,维护起来超麻烦。不行!看来我得寻找一个新的、可读性更高的数据储存方式了!”小白吼道。

“一个新的数据储存方式?该在哪才能找到这个新的数据储存方式呢?”小白思索道,他想起了他以前的知识几乎都是从《简明》 学来的。那么简明教程会不会有他这次想找的东西呢?小白翻开简明,他发现以前有关数据处理的 list 办法是出自于简明中 数据结构 一章。他想:“list 办法是出自这章的,那么,这章会不会有一些别的储存方式比这个 list 更简便的呢?”小白决定仔细看看简明中 数据结构 这章。

一点开这章,他就看到了这些东西:

“数据结构基本上就是——它们是可以处理一些 数据 的 结构 。或者说,它们是用来存储一组相关数据的。

在Python中有三种内建的数据结构——列表、元组和字典。我们将会学习如何使用它们,以及它们如何使编程变得简单”

“对,数据结构就是用来储存某些数据的,我只时用了数据结构中的列表,还有三个数据结构我没有学呢!”小白思索道。他感觉,这一节中就有他想要的东西。他仔细地,一页一页的继续看下去。突然他眼前一亮,发现了这些内容:

../_images/ch01-5-dict.png

“字典?联系人?这也太巧了吧!怎么它的实例和我想做的是同一件东西”小白继续看下去,当他看到了简明中字典的实例和输出“Oh,这是神马东西嘛,输出这么乱,完全看不懂,还是自己试试看把它上面的实例打到 IDLE 里看会怎样吧!”

小白在 Idle 中输入了实例中的语句,并进行了自己的理解。

#(实例引用自简明)
>>> ab = {       'Swaroop'   : 'swaroopch@byteofpython.info',
             'Larry'     : 'larry@wall.org',
             'Matsumoto' : 'matz@ruby-lang.org',
             'Spammer'   : 'spammer@hotmail.com'
     }    #这里应该就是新定义一个字典吧?

>>> print ab
{'Swaroop': 'swaroopch@byteofpython.info', 'Matsumoto': 'matz@ruby-lang.org', 'Larry': 'larry@wall.org', 'Spammer': 'spammer@hotmail.com'}  #果然新定义了一个字典
>>> print "Swaroop's address is %s" % ab['Swaroop']     #咦?print 后面跟了一个 ab['Swaroop'] 难道这是读取 ab 中的 Swaroop?
Swaroop's address is swaroopch@byteofpython.info       #好像是输出 Swaroop 后面的信息 swaroopch@byteofpython.info 了。
>>> print ab['Swaroop']                       #试试单独打印 ab['Swaroop'] 试试
swaroopch@byteofpython.info                  #哇塞,果然输出了 ab['Swaroop'] 后面的值,看来只要用 字典名['字典中要读取的键'] 这种格式就能读取到字典中的值了
>>> ab['Guido'] = 'guido@python.org'           #这句有事干什么用呢?字典 ab 中并没有 Guido 这个键啊?
>>> print ab['Guido']                         #打印 Guido ?可字典里面没有这个键啊?
guido@python.org                                #字典中好像又多了 Guido 这个键了,莫非上一句是在字典中添加 Guido 这个键吗?赶快看看!
>>> print ab
{'Swaroop': 'swaroopch@byteofpython.info', 'Matsumoto': 'matz@ruby-lang.org', 'Larry': 'larry@wall.org', 'Spammer'   : 'spammer@hotmail.com','Guido': 'guido@python.org'}    #果然多出了 Guido 这个键,看来那一句果然是用于添加字典中的键值的
>>> del ab['Spammer']           #del?删?难道这是删除字典中的某个键吗?
>>> print ab['Spammer']         #打印出来看看?

Traceback (most recent call last):                  #出错,看来果然是删掉那个键值了
  File "<pyshell#7>", line 1, in <module>
    print ab['Spammer']
KeyError: 'Spammer'
>>>

“哈哈,这个字典真是太好用了,竟然能通过对应的键列出对应的值,太棒了,这样我的通信录又能简化不少啊,连 list 都不用用了,而且看着还清楚,真是太方便了”小白迫不及待想要把他的通信录改成用字典的通信录。“对,咱就先用字典实现读取联系人功能,再实现添加联系人功能,一步步来。”小白马上动起手来。

_Info = {"张三":54321,
     "李四":12345}
_run = True
while _run:
    _User_input = raw_input("输入联系人名:")
    print _Info[_User_input]

小白尝试着运行它的程序:

>>>
输入联系人名:张三
54321
输入联系人名:李四
12345
输入联系人名:王五

Traceback (most recent call last):
  File "E:/test.py", line 7, in <module>
    print _Info[_User_input]
KeyError: '\xcd\xf5\xce\xe5'
>>>

“对哇,没有作一个判断,以判断用户输入的键是否在字典里,这样的话如果用户输入一个不存在的键的话,程序就会像这样报错了,可是,怎样才能判断字典里面有没有某个键呢?直接读取不存在的键是肯定不行的呀,这样肯定出错!有没有判断一个字典里面有没有某个键的办法呢?”这时,小白想到了一个绝对能找到答案的办法:python 的 help()

“对嘛,前面早就已经知道python有help()这个办法了,为何不用一下呢?”小白在简明中已经知道了字典的E文是 dict 。“那么,只要 help(dict) 不就可以查看到所有有关字典的用法了吗?”小白马上动手。

>>> help(dict)
Help on class dict in module __builtin__:

class dict(object)
 |  dict() -> new empty dictionary
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs
 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)
 |
 |  Methods defined here:
 |
 |  __cmp__(...)
 |      x.__cmp__(y) <==> cmp(x,y)
 |
 |  __contains__(...)
 |      D.__contains__(k) -> True if D has a key k, else False
 |
 |  __delitem__(...)
 |      x.__delitem__(y) <==> del x[y]
 |
 |  __eq__(...)
 |      x.__eq__(y) <==> x==y
 |
 |  __ge__(...)
 |      x.__ge__(y) <==> x>=y
 |
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |
 |  __gt__(...)
 |      x.__gt__(y) <==> x>y
 |
 |  __init__(...)
 |      x.__init__(...) initializes x; see help(type(x)) for signature
 |
 |  __iter__(...)
 |      x.__iter__() <==> iter(x)
 |
 |  __le__(...)
 |      x.__le__(y) <==> x<=y
 |
 |  __len__(...)
 |      x.__len__() <==> len(x)
 |
 |  __lt__(...)
 |      x.__lt__(y) <==> x<y
 |
 |  __ne__(...)
 |      x.__ne__(y) <==> x!=y
 |
 |  __repr__(...)
 |      x.__repr__() <==> repr(x)
 |
 |  __setitem__(...)
 |      x.__setitem__(i, y) <==> x[i]=y
 |
 |  __sizeof__(...)
 |      D.__sizeof__() -> size of D in memory, in bytes
 |
 |  clear(...)
 |      D.clear() -> None.  Remove all items from D.
 |
 |  copy(...)
 |      D.copy() -> a shallow copy of D
 |
 |  get(...)
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
 |
 |  has_key(...)
 |      D.has_key(k) -> True if D has a key k, else False
 |
 |  items(...)
 |      D.items() -> list of D's (key, value) pairs, as 2-tuples
 |
 |  iteritems(...)
 |      D.iteritems() -> an iterator over the (key, value) items of D
 |
 |  iterkeys(...)
 |      D.iterkeys() -> an iterator over the keys of D

 ......

小白仔细观察 help 出来的东东,这时,一个叫 has_key 的东东吸引了他的注意:

|  has_key(...)
|      D.has_key(k) -> True if D has a key k, else False

“True if D has a key k, else False?如果字典 D 有键 k 就返回 True,否则返回 False?这正是我需要的!看样子,它的用法就是 D.has_key(k) 嘛,马上试一下看到底是不是这样用的!”小白马上打开 IDLE 进行了尝试:

>>> _Info = {"张三":54321,
        "李四":12345}
>>>
>>> _Info.has_key("张三")
True
>>> _Info.has_key("hello")
False
>>>

“哈哈,真的是这样。接下来只要在在原程序上加个 if ,用 has_key 判断就可以了。”小白迅速动作:

_Info = {"张三":54321,
        "李四":12345}

_run = True
while _run:
    _User_input = raw_input("输入联系人名:")
    if _Info.has_key(_User_input) == True:
        print _Info[_User_input]
    elif _User_input == "退出":
        _run = False
    else:
        print "无此联系人"

“运行试试。”小白对他的程序进行调试。

>>>
输入联系人名:张三
54321
输入联系人名:李四
12345
输入联系人名:王五
无此联系人
输入联系人名:退出
>>>

小白敲打着键盘:“Ok,成功,一切都在意料之中,这字典真是太方便了,接下来就是把我已经知道的 ab[‘Guido’] = 'guido@python.org‘ 这个用法添加到程序中就能实现联系人添加功能了。”:

_Info = {"张三":54321,
        "李四":12345}

_run = True
while _run:
    _User_input = raw_input("输入联系人名:")
    if _Info.has_key(_User_input) == True:
        print _Info[_User_input]
    elif _User_input == "增加":
        _New_Name = raw_input("输入要增加的联系人名:")
        _New_Info = raw_input("输入该联系人的信息:")
        _Info[_New_Name] = _New_Info
    elif _User_input == "退出":
        _run = False
    else:
        print "无此联系人"

“搞定!调试一下程序看会不会有问题。”小白想。

输入联系人名:张三
54321
输入联系人名:李四
12345
输入联系人名:王五
无此联系人
输入联系人名:增加
输入要增加的联系人名:王二麻子
输入该联系人的信息:123333
输入联系人名:王二麻子
123333
输入联系人名:退出
>>>

“好,程序果然没有问题。诶?”小白敲了敲自己的脑袋。“如果这样做的话就会有一个 bug ,用户退出了程序之后他添加的联系人就全都没了!前面的 list 通信录添加功能也有这个问题,怎样才能解决他们呢?”小白又陷入新的思考中......

(第一章完)