RWPy4learner 11.3.30 documentation

Version: 11.3.30
[首页] 用if判断 << 更加简化的通信录 (Source) >>再次优化通信录

更加简化的通信录

“太多 if 和变量啊!!!这太烦了,要打到什么时候啊!总不可能用这么多的变量去储存所有的联系人信息吧......太可怕了,太麻烦了!”坐在屏幕前的小白仰天大吼了一声。

“有没有一种办法能用更少的变量来储存所有联系人的信息呢?”小白狂吼道!

冷静下来的小白想到了《简明 Python 教程》,”平时俺的问题基本上都能在上面得到解决,那么,到上面看看有没有我所需要的呢?“

找啊,找啊,小白左翻翻右翻翻,”好像什么也没有找到啊!“小白郁闷道,”不如这次就到列表上问问看有没有这种能用更少的变量来储存所有联系人的信息的办法吧,这个我觉得已经可以不算是小白问题了吧?“小白想。

小白打开 gmail ,迅速地在上面发了一封邮件:

标题:能用更少的变量来储存所有的信息呢
内容:
   我在做一个软件,里面用到了非常多的变量,这非常不便于管理,是否能用更少的变量来储存所有信息呢?

”小白等啊等啊,终于,他等到了回复。“

可以使用 list 储存信息,这样可以非常方便调用。必要时可以用 for 语句处理全部 list 中的信息。

“list 和 for ?”小白纳闷道“这两个东西我可都是从来没有见过啊?”不过先不管了,既然知道了这两个名词,那就先到简明上去找找看有没有相关名词进行学习吧”小白迅速打开简明进行查找,果然,他找到了:

../_images/ch01-4-list.png

小白内心沸腾了!“储存一个“序列”的项目,这不正是我想要的嘛!可是,下面的那个例子我没有办法解读啊,它有一些我不会的语句,不如就先去 bing 找找看有没有更简单一些、我能看得懂的的实例吧。”

“好,马上,Bing下先!”小白打开 bing ,“在简明中我已经知道了 list 的中文名字叫 列表,那么好,我就在搜索关键词中输入 “python 列表”看看会有什么结果。”小白想

小白在浏览器上输入网址:cn.bing.com 搜索:python 列表 Enter!

第一个搜索结果就有介绍,点开看看啊:

../_images/ch01-4-list2.png

打开网页后,小白看到了这样的东东:

../_images/ch01-4-list3.png

“嗯。“value_start = ”、“end_value = ”“sample_list = ”是熟悉的赋值变量语句。。删除一个值?读取 一个值?这些都是什么东西呢?”小白想“这个 sample_list 后面跟着一个 [‘a’,’b’,0,1,3] 这个应该就是列表吧?列表中放着的那些 ‘a’,’b’,0,1,3 应该就是储存在列表里的信息吧?”小白思索道。“还是先什么都不管了,就先把这代码拿到 IDLE 里试试看会有什么结果吧,反正网页上代码都已经给出来了,试试说不定就能看出个所以然来,先拿简单的读取操作来试试吧!反正我的程序里只需要一个读取操作。”

>>> sample_list = ['a','b',0,1,3]
>>> value_start = sample_list[0]
>>> print value_start
a
>>> end_value = sample_list[-1]
>>> print end_value
3
>>>

小白在 IDLE 中打进了程序中进行实验,很快,他发现了这些问题:

1.0?这是什么意思?

2.-1 又是什么意思呢

”如果把 0 换成 1 会怎么样呢?“小白想”不管了,先试试看看会如何。“

>>> sample_list = ['a','b',0,1,3]
>>> print sample_list[0]
a
>>> print sample_list[1]
b
>>> print sample_list[2]
0
>>> print sample_list[3]
1
>>> print sample_list[4]
3
>>> print sample_list[5]

Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    print sample_list[5]
IndexError: list index out of range
>>>

“哦,我明白了,0 读取出了列表中的 a ,1 读取出了列表中的 b , 2 读取出了列表中的 0...... 这不是按照列表中的东东 ‘a’,’b’,0,1,3 的先后顺序读取的吗!原来 Python 是从 0 开始计数的!我明白了!!!“小白狂吼道。”那么,网页中的那段代码 end_value = sample_list[-1] 是不是就是从后面开始读取起来的呢?毕竟是 -1 嘛。”小白迅速在 IDLE 中敲下代码。

>>> sample_list = ['a','b',0,1,3]
>>> print sample_list[-1]
3
>>> print sample_list[-2]
1
>>> print sample_list[-3]
0
>>>

“OMG!果然是这样!”小白为依靠自己力量又成功的解决了一个感到兴奋。“可是,这列表用起来好像还是省不了多少步骤啊,如果是要调用列表中的东东的话,还是得用 sample_list[0]、sample_list[1] ... 这样调用,虽然是省了很多变量,但是却省不了 if 啊?还是要写很多的 if ,这只是方便了联系人信息的管理罢了。”小白突然灵光一现:“对哇,行者不是还说过有一个叫 for 的东西可以处理全部 list 中的信息。这个 for 到底能不能实现处理全部 list 中的信息呢?先不管了,无论多渺小的机会都要抓住!先到简明上看看这个东西再说。”小白想。

小白翻开简明,迅速找到了 for 这个章节。

../_images/ch01-4-list4.png

接着,小白看到了输出:

../_images/ch01-4-list5.png

”递归 即逐一使用队列中的每个项目。这是什么意思呢?这个 range 是什么意思呢?他下面为什么会有 1,2,3,4 这样的输出呢?“小白百思不得其解,他郁闷地敲击着键盘,胡乱地复制着代码。突然,他胡乱地把一段代码复制到 IDLE 运行后,有了新发现。

>>> range(1,5)
[1, 2, 3, 4]
>>>

”哇靠,range(1,5) 竟然返回了一个 [1, 2, 3, 4] 的列表,难道这里 for 的后面的 range(1,5) 其实等同于一个列表来的吗?“小白在 IDLE 中进行了 range 的实验。

>>> range(1,5)
[1, 2, 3, 4]
>>> range(1,3)
[1, 2]
>>> range(1,4)
[1, 2, 3]
>>> range(0,5)
[0, 1, 2, 3, 4]
>>> print range(1,6)
[1, 2, 3, 4, 5]
>>>

“果然是这样: range(x,y)的话会把x数 到 y数 中的数都返回到列表里,而且返回的最后一个值是 y-1 。”小白明白了range的含义。“可是,为什么简明教程中的实例最后 print 出来的是 1,2,3,4 呢?这个好像还是有些难理解。先不管了,既然 range 返回的是一个列表,那么就是说把它换成我自己的列表不也可以顺利执行 for 语句吗?先让这 for 顺利动起来再说!”小白决定暂且先放下刚刚他所发现的问题,走一步算一步。

>>> for i in ['a','b',0,1,3]:
     print i


a
b
0
1
3
>>>

“哦?难道?!难道?!我明白了!”小白高呼:“原来它是依次把列表中的项目 ‘a’,’b’,0,1,3 赋值给 i 然后循环打印出i来。如果是这样的话,最后一个赋值给 i 的应该是列表里的最后一个项目 3 吧?”小白思索道“如果最后一个赋值给 i 的是 3 那么就证明我的结论成立!那么,只要 print 一下 i 变量就可以知道我的推断是否成立了”小白迅速打开 IDLE ,敲下键盘:

>>> print i
3
>>>

“哈哈,果然是这样,结论证明完成“小白高兴道,接下来就是看看如何把它融合到我的程序中”小白马上开干:

_Name = raw_input("输入名字:")

Info_list = ["张三",123456,"李四",54321]

Num = 0
for i in Info_list:
    if _Name == i:
        print Info_list[Num+1]
        Num = Num + 1
    else:
        Num = Num + 1

“搞定!”小白吼道。“我这个程序结构真是太巧妙了,当用户输入联系人后, for 进行判断,当判断正确后,就会 +1 读取联系人后面的值,而我在联系人后面的就是联系人的号码!”小白为自己的设计感到无比的自豪:“果然行者说的没错,用 for 和 if 果然就能简化掉很多的程序。”

小白兴奋的把程序那回到班上给大家试用,大家使用了一阵子后,同学就普遍反馈了一个问题:“这个通信录就只有这个功能吗?只有查询功能不太实用啊。如果有个添加联系人的功能话,就能自己添加自己想添加的同学,那就实用多了。”。

“同学说得也对,这样的通信录还不能称之为真正的通信录,看来还要进一步对它进行完善”小白想。

“好,为了让我的程序更加易用,拥有添加联系人的功能是必不可少的。我已经用 list 成功的实现了一个拥有查询功能的通信录了。那么,能不能在现有 list 的基础上,继续完善程序,使程序拥有添加联系人的功能呢?“小白对目前的形式进行了分析:“我们目前显示联系人的方式是通过打印 list 中的一个姓名值(包含联系人姓名的值)和这个值后面的一个电话值(包含联系人电话的值)进行的。如果要实现添加联系人的功能,就得往 list 中添加两个值:一个姓名值和一个电话值,这样的话,我原先设计的查找联系人程序就也能适用于这个含有新添加的联系人信息的列表了。按照这样计算的话,下面只要找到在列表中添加新值的办法就行了。”

小白打开 IDLE ,输入 help(list) 查找在 list 中添加新值的办法。很快,他就发现了这样一个东东:

|  append(...)
|      L.append(object) -- append object to end

“append object to end?这不是增加元素到最后的意思吗?最后?这会不会指的是列表的坐后面呢?L 在这里代表的是存放列表的那个变量的名称吧?”一切的猜想充斥着小白的思维,小白决定到 IDLE 中试一试他所做的猜想是否正确。

>>> a=[1,2,3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>>

“嗯,看来的确是这样,我的猜想都没有错,a.append(4) 果然把 4 添加到了 [1,2,3] 的最后。既然已经知道了如何人在 list 中添加一个新值,那么,下面,只要把他写到我的程序里就可以了。由于我的程序是通过打印一个姓名值和一个电话值来显示联系人的信息的,if 语句判断的也只是姓名值而已。那么只要在列表里按照 [...,姓名值,电话值,姓名值,电话值,姓名值,电话值,...] 这种模式进行联系人的添加就可以了。下面要做的,只要写两个 raw_input 让用户分别输入姓名值和电话值,这个程序就算完成了。”小白规划好了它的代码应该如何编写,接下来就是要把程序做出来。

_Name = raw_input("输入名字:")

Info_list = ["张三",123456,"李四",54321]

Num = 0
if _Name == "添加":
        _add_Name = raw_input("输入新联系人名:")
        _add_Info = raw_input("输入新联系人电话:")
        Info_list.append(_add_Name)
        Info_list.append(_add_Info)
for i in Info_list:
    if _Name == i:
        print Info_list[Num+1]
        Num = Num + 1
    else:
        Num = Num + 1

小白调试程序,他很快就发现了一个新的问题:

>>> ================================ RESTART ================================
>>>
输入名字:添加
输入新联系人名:王五
输入新联系人电话:123
>>> ================================ RESTART ================================
>>>
输入名字:王五
>>>

“咦?怎么第二次运行就不能显示我新增的联系人 王五 的信息呢?”。他发现它的程序只是运行了一遍就退出了,那么自然,退出后那个新增了联系人姓名值和电话值的列表也就没有了。“这样的话,那我的这个添加功能岂不是白做?”小白非常郁闷,自己刚做好的联系人添加功能竟然没有发挥作用。仔细一看,小白才发现他的程序没有加 while 语句。“我真是个大马哈啊,怪不得会这样,赶快加上。”

Info_list = ["张三",123456,"李四",54321]

Num = 0

_run = True
while _run:
    _Name = raw_input("输入名字:")
    if _Name == "添加":
        _add_Name = raw_input("输入新联系人名:")
        _add_Info = raw_input("输入新联系人电话:")
        Info_list.append(_add_Name)
        Info_list.append(_add_Info)
    if _Name == "退出":
        _run = False
    for i in Info_list:
        if _Name == i:
            print Info_list[Num+1]
            Num = Num + 1
        else:
            Num = Num + 1

“调试一下!!”。小白激动的敲着键盘。可接下来的结果却让他大跌眼镜。

>>> ================================ RESTART ================================
>>>
输入名字:李四
54321
输入名字:添加
输入新联系人名:王五
输入新联系人电话:123
输入名字:王五
Traceback (most recent call last):
  File "C:\Documents and Settings\Administrator.COMPUTER\桌面\Test.py", line 20, in <module>
    print Info_list[Num+1]
IndexError: list index out of range

“list index out of range??!这是怎么回事,好像是因为 Num+1 的值超出了列表的范围!怎么会这样?”小白一遍又一遍的运行程序,然后仔细观察输出,他发现,每次都是运行到第二次:输入名字 的时候会出错。“为什么会这样呢?问题应该就是出在 Num+1 上,我的程序就是通过这个获取列表中对应的值然后打印,超出范围的话...难道是说这个值太大了吗?而且均在第二次运行发生异常。”突然小白灵光一现:“我明白了,第一次执行的时候 Num 是等于 0 的,执行完一次之后到第二次时,由于 Num 并没有恢复为原来的 0,在没有复 0 的时候执行第二次,在提取列表值的时候自然就会超出列表的范围出错了!”小白成功分析出他程序的问题所在,他在它的程序 while 的开头加了个 Num = 0 ,每次执行完一次之后就复 0 。

Info_list = ["张三",123456,"李四",54321]

_run = True
while _run:
    Num = 0
    _Name = raw_input("输入名字:")
    if _Name == "添加":
        _add_Name = raw_input("输入新联系人名:")
        _add_Info = raw_input("输入新联系人电话:")
        Info_list.append(_add_Name)
        Info_list.append(_add_Info)
    if _Name == "退出":
        _run = False
    for i in Info_list:
        if _Name == i:
            print Info_list[Num+1]
            Num = Num + 1
        else:
            Num = Num + 1

“Ok,搞定,既然在 while 开头加了 Num = 0 那么程序的开头就没必要再定义 Num = 0 了,两句意思功效一样吗!”。小白手指一动删掉了程序开头那句 Num = 0。“Ok,执行一遍看看!”小白敲下 F5.

输入名字:李四
54321
输入名字:添加
输入新联系人名:王五
输入新联系人电话:123
输入名字:王五
123

“Ok,搞定,又一难题解决”小白兴奋道!