"Come to me, all you that are weary and are carrying heavy burdens,and I will give you rest. Take my yoke upon you, and learn from me; for I am gentle and humble in heart, and you will find rest for your souls. For my yoke is easy, and my burden is light." (MATTHEW 21:28-30)

“凡劳苦担重担的人,可以到我这里来,我就使你们得安息。我心里柔和谦卑,你们当负我的轭,学我的样式,这样,你们心里就必得享安息。因为我的轭是容易的,我的担子是轻省的。”

列表(3)

接着上节内容。下面是上节中说好要介绍的列表方法:

'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'

已经在上节讲解了前四个。

继续。

list函数

insert

append()或者extend()都是向列表中追加元素,“追加”是且只能是将新元素添加在list的最后一个。如:

>>> all_users = ["qiwsir","github"]
>>> all_users.append("io")
>>> all_users
['qiwsir', 'github', 'io']

list.append(x)类似,list.insert(i,x)也是对list元素的增加。只不过是可以在任何位置增加一个元素。

官方文档如是说:

list.insert(i, x)

Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).

这次就不翻译了。如果看不懂英语,怎么了解贵国呢?一定要硬着头皮看英语,不仅能够学好程序,更能...(此处省略两千字)

根据官方文档的说明,我们做下面的实验:

>>> all_users = ['qiwsir', 'github', 'io']
>>> all_users.insert("python")      
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: insert() takes exactly 2 arguments (1 given)

请注意看报错的提示信息,insert()应该供给两个参数,但是这里只给了一个。所以报错没商量啦。

>>> all_users.insert(0,"python")
>>> all_users
['python', 'qiwsir', 'github', 'io']

>>> all_users.insert(1,"http://")
>>> all_users
['python', 'http://', 'qiwsir', 'github', 'io']

list.insert(i, x)中的i是将元素x插入到列表中的位置,即将x插入到索引是i的元素前面。注意,索引是从0开始的。

有一种操作,挺有意思的,如下:

>>> length = len(all_users)
>>> length
5       
>>> all_users.insert(length,"algorithm")
>>> all_users
['python', 'http://', 'qiwsir', 'github', 'io', 'algorithm']

在all_users中,没有索引5,最大到4。如果要all_users.insert(5,"algorithm"),则表示将"algorithm"插入到索引值是5的前面,但是没有。换个说法,5前面就是4的后面。所以,就是追加了。

其实,还可以这样:

>>> a = [1, 2, 3]
>>> a.insert(9, 777)
>>> a
[1, 2, 3, 777]

也就是说,如果遇到那个i已经超过了最大索引值,会自动将所要插入的元素放到列表的尾部,即追加。

只不过,这样做的不多罢了。

最后,还要关注,insert()也是对列表原地修改,没有返回值,或者说返回值是None

pop和remove

列表中的元素,不仅能增加,还能被删除。删除列表元素的方法有两个,它们分别是:

list.remove(x)

Remove the first item from the list whose value is x. It is an error if there is no such item.

list.pop([i])

Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)

读者如果一直跟着我的节奏在学习,应该体会到我们这里的一种学习方法了——先实验,然后总结规律。这是一种物理学的研究方法。

物理学,是科学的基础,特别是它所演化出来的科学研究方法,更是人类智慧的瑰宝。不忘初心,我是大物理系毕业的。

先实验list.remove(x),注意看上面的描述。这是一个能够删除列表元素的方法,同时上面说明告诉我们,如果x没有在list中,会报错。

>>> all_users = ['python', 'http://', 'qiwsir', 'github', 'io', 'algorithm']
>>> all_users.remove("http://")
>>> all_users                 #的确是把"http://"删除了
['python', 'qiwsir', 'github', 'io', 'algorithm']

在all_users所指向的列表中删除一个元素,一切都符合文档说明的要求,很顺利地完成了。

>>> all_users.remove("tianchao")        #原list中没有“tianchao”,要删除,就报错。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list

如果列表中没有那个元素,非要删除不可,肯定报错。而且报错信息非常明确指出x not in list。这也是文档中已经陈述过的了。

>>> lst = ["python","java","python","c"]
>>> lst.remove("python")
>>> lst
['java', 'python', 'c']

仔细观察,变量的名字lst,不是list,最好不要用list作为变量名字,因为它是Python中内置的对象类型的名字,如果你非要用它做变量名字,很可能引起后续的麻烦。

再仔细观察,这个列表中有两个'python'字符串,当删除后,发现结果只删除了第一个'python'字符串,第二个还在。请仔细看前面的文档说明:remove the first item ...

所以,对remove()总结两点:

  • 如果正确删除,则删除第一个符合条件的对象。不会有任何反馈。没有消息就是好消息。它是对列表进行原地修改。
  • 如果所删除的内容不在列表中,就报错。注意阅读报错信息:x not in list

对于删除,能不能更友好一些?在删除之前,先判断一下这个元素是不是在列表中,如果在就删,不在就不删。

如果读者想到这里,就是在编程的旅程上一进步。Python的确让我们这么做。

>>> all_users
['python', 'qiwsir', 'github', 'io', 'algorithm']
>>> "python" in all_users            #这里用in来判断一个元素是否在list中,在则返回True,否则返回False
True

>>> if "python" in all_users:
...     all_users.remove("python")
...     print all_users
... else:
...     print "'python' is not in all_users"
... 
['qiwsir', 'github', 'io', 'algorithm']     #删除了"python"元素

>>> if "python" in all_users:
...     all_users.remove("python")
...     print all_users
... else:
...     print "'python' is not in all_users"
... 
'python' is not in all_users        #因为已经删除了,所以就没有了。

上述代码,就是两段小程序,我是在交互模式中运行的,相当于小实验。

这里其实用了一个后面才会讲到的东西:if-else语句。

不过,我觉得即使没有学习,你也能看懂,因为它非常接近自然语言了——这也正是Python语言的特点之一。

对于remove(),还有最后一个要交代的,它对列表的修改也是原地修改,正确实现删除后没有返回值。

另外一个删除list.pop([i])会怎么样呢?看看文档,做做实验。

>>> all_users = ['qiwsir', 'github', 'io', 'algorithm']
>>> all_users.pop()             
'algorithm'                              
>>> all_users
['qiwsir', 'github', 'io']

list.pop([i]),圆括号里面是[i],表示这个参数是可选的,如果不写,也就是圆括号为空,默认删除最后一个,并且将删除的元素作为结果返回。提醒读者注意,它有返回值。

如果参数不为空,可以删除指定索引的元素,并将该元素作为返回值。

>>> all_users.pop(1)        #指定删除编号为1的元素"github"
'github'

>>> all_users
['qiwsir', 'io']
>>> all_users.pop()
'io'

>>> all_users           #只有一个元素了,该元素编号是0
['qiwsir']
>>> all_users.pop(1)          #但是非要删除编号为1的元素,结果报错。注意看报错信息
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: pop index out of range      #删除索引超出范围,就是1不在list的编号范围之内

简单总结一下:

  • list.remove(x)中的参数是列表中元素,即删除某个元素,且对列表原地修改,无返回值
  • list.pop([i])中的i是列表中元素的索引值,可选。为空则删除列表最后一个,否则删除索引为i的元素。并且将删除元素作为返回值。

给读者留下一个思考题,能不能事先判断一下要删除的元素的索引是不是在列表的长度范围(用len(list)获取长度)以内?然后进行删除或者不删除操作。

reverse

reverse比较简单,就是把列表的元素顺序反过来。

>>> a = [3,5,1,6]
>>> a.reverse()
>>> a
[6, 1, 5, 3]

注意,是原地反过来,不是另外生成一个新的列表。所以,它没有返回值。

跟本函数类似的有一个内建函数reversed,建议读者了解一下这个函数的使用方法。

因为list.reverse()不返回值,所以不能实现对列表的反向迭代,如果要这么做,可以使用reversed函数。

sort

sort就是对列表进行排序。输入help(list.sort)调用帮助文档,可以得到如下内容(Python2和Python3略有差异)。

>>> #Python 2
>>> help(list.sort)
Help on method_descriptor:

sort(...)
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1

>>> #Python 3
>>> help(list.sort)
Help on method_descriptor:

sort(...)
    L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*

虽然文档说明中略有差异(读者通过本书以前的内容,应该能够理解差异的缘由),但是不影响操作。

>>> a = [6, 1, 5, 3]
>>> a.sort()
>>> a
[1, 3, 5, 6]

list.sort()也是让列表进行原地修改,没有返回值。默认情况,如上面操作,实现的是从小到大的排序。

>>> a.sort(reverse=True)
>>> a
[6, 5, 3, 1]

这样做,就实现了从大到小的排序。

在前面的函数说明中,还有一个参数key,这个怎么用呢?不知道读者是否用过电子表格,里面就是能够设置按照哪个关键字进行排序。这里也是如此。

>>> lst = ["python","java","c","pascal","basic"]
>>> lst.sort(key=len)
>>> lst
['c', 'java', 'basic', 'python', 'pascal']

这是以字符串的长度为关键词进行排序。

对于排序,也有一个更为常用的内建函数sorted(),你可以去探究一下用法。

顺便指出,排序是一个非常有研究价值的话题。不仅仅是现在这么一个函数。有兴趣的读者可以去网上搜一下排序相关知识。

最后,对前文提到的“保留字”基于补充说明。

什么是保留字?在Python中,当然别的语言中也是如此啦。某些词语或者拼写是不能被用户拿来做变量/函数/类等命名,因为它们已经被语言本身先占用了。这些就是所谓保留字。在Python中,以下是保留字,不能用于你自己变成中的任何命名。

在Python 2和Python 3中,都可以用下面的方式查看保留字,而且,注意,两个不同版本的保留字还有差别,虽然差别很小。

Python 2中:

>>> import keyword
>>> keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
>>> len(keyword.kwlist)
31

Python 3中:

>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
>>> len(keyword.kwlist)
33

列表的方法已经结束,但是列表的话题还没有完结,因为它还能和“字符串”搞在一起,需要辨析一番。


总目录   |   上节:列表(2)   |   下节:列表和字符串

如果你认为有必要打赏我,请通过支付宝:[email protected],不胜感激。

results matching ""

    No results matching ""