Python学习之旅:list

list 是类似 C 语言中的数组的东西,但是它其中的构造比数组要复杂的多,是 Python 中自带的一个类型,包含了多种方法和成员。
既然与数组类似,那么 list 里面的成员一定也是有序的集合。但是相比与数组,我们又可以随时自由的添加或者删除里面的成员,甚至是插入。

与传统 C 的联系

声明 list

list 和 [] 中括号有着直接的关系,无论是声明还是取出,都需要通过中括号实现。
声明一个 list 可以通过 = 等号来对一个变量名进行赋值为 list,例如:

1
2
3
4
5
6
7
8
9
10
>>> student = []
>>> classmates = ['Mike', 'Jason', 'Kate']
>>> price = [3.99, 6.47, 1.66, 7.7]
>>>
>>> student
[]
>>> classmates
['Mike', 'Jason', 'Kate']
>>> price
[3.99, 6.47, 1.66, 7.7]

从上面的代码可以看到,在 Python 的解释器中,通过 = 等号声明之后,变量名就自动变为一个 list 了,在解释器中直接输入变量名 Python 解释器就会直接把这个 list 对象输出。

取出

因为 list 是通过下标来进行成员的定位的,按照定义可以通过 [] 中括号对 list 进行指定的成员取出,例如:

1
2
3
4
5
6
7
8
9
10
>>> classmates[0]
'Mike'
>>> classmates[1]
'Jason'
>>> classmates[2]
'Kate'
>>> classmates[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

从代码可以看出,Python 还是和传统的编程语言一样,元素编号从0开始,延续了程序员的传统。
但是和传统编程语言不同的是,Python 还提供倒序下标的取出,例如:

1
2
3
4
5
6
7
8
9
10
>>> classmates[-1]
'Kate'
>>> classmates[-2]
'Jason'
>>> classmates[-3]
'Mike'
>>> classmates[-4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

可以看出,Python 这一点显得和人性化,可以通过负数下标进行倒序的取出,这是十分方便的,但是其中的实现过程用掉了的性能的多少也不难理解了吧。

成员赋值

赋值和传统的编程语言相同,一般都为【取出】->【修改】两个步骤。和传统的 C 相同:

1
2
3
4
5
>>> classmates
['Mike', 'Jason', 'Kate']
>>> classmates[1] = 'SmallXeon'
>>> classmates
['Mike', 'SmallXeon', 'Kate']

这样就实现了修改成员。

成员方法(与传统的数组不同的地方

获取长度 len()

熟悉 C 的话就可以知道需要获得数组的长度需要一连串的操作,获取占用的内存字节、获取成员的大小、总内存大小除成员的内存大小,结合起来就是 int lenth = sizeof(array1) / sizeof(array1[0]); 这样一串复杂的操作,对新手也不友好。

而 Python 中人性化的一点就是用了通用的函数对其直接处理就可以返回我们需要的数据。

1
2
3
4
>>> classmates
['Mike', 'SmallXeon', 'Kate']
>>> len(classmates)
3

我们可以看到,我们使用 Python 中的通用函数 len() 可以直接读取到 list 的长度。
len() 不难理解,就是我们英文单词中的 lenth 的缩写,对于新手来说也可以通过猜而一知半解。我们在 Python 解释器中查看 len() 函数的定义:

1
2
>>> len
<built-in function len>

可以看到是显示的是一个内建的函数,既然是内建的函数,那么多数可以用在内建的类型——list 上。

添加成员

说到数组,有一个问题困扰了新手时期的我很久,就是如何给数组添加新的成员呢?

拷贝原数组到一个新的数组中:获取原数组长度;由于 C 不支持动态数组的声明,所以需要在内存的层面直接分配新数组大小;拷贝成员。总结一下就是一下几点步骤:

1
2
3
4
int lenth = sizeof(array_old) / sizeof(array_old[0]);
type *array_new = (type *)malloc(sizeof(type) * (lenth + 1));
for (int i = 0; i < lenth; i++)
array_new[i] = array_old[i];

这样一段复杂的操作之后,数组就延长了,但是随之而来的问题就是数组名发生了改变。再后来,遇到了和 malloc() 一起的 realloc() 函数之后,问题又简单了一些:

1
2
int lenth = sizeof(array_old) / sizeof(array_old[0]);
array = (type *)realloc(array, sizeof(array[0]) * (lenth + 1));

但是缺点还是会存在,因为想要使用 realloc() 函数重新分配内存的话,那么内存名就必须是由malloc()realloc()alloc()分配的内存。这就十分的不方便了。


由上可以看出,在传统 C 中延长一个数组是有多么的麻烦(充满程序员艺术美?我竟然沉迷其中)。
而 Python 里面只需要简单的一步就可以直接实现对 list 的添加、插入、弹出

尾部链接新成员 append()

list 类型自带一个 append() 方法,将元素自然的链接到 list 的尾部,实现 list 的延长:

1
2
3
4
5
>>> classmates
['Mike', 'SmallXeon', 'Kate']
>>> classmates.append('Smith') # 实际上只有这步在操作
>>> classmates
['Mike', 'SmallXeon', 'Kate', 'Smith']

可以看出,这是让 C 的程序员很眼红的事情了,只需要一个 append() 就可以延长数组并且添加元素的操作。只能叹服…

中间插入成员 insert()

插入成员,在 C 中更是一度作为考题来对程序员的能力进行考核。而 Python 则又是让人眼红不已:

1
2
3
4
5
>>> classmates
['Mike', 'SmallXeon', 'Kate', 'Smith']
>>> classmates.insert(2, 'Ubuntu') # 实际上只有这步操作
>>> classmates
['Mike', 'SmallXeon', 'Ubuntu', 'Kate', 'Smith']

删除成员

通用删除函数 del

删除 list 的指定成员,可以直接是使用 del 来删除:

1
2
3
4
5
>>> classmates
['Mike', 'SmallXeon', 'Ubuntu', 'Kate', 'Smith']
>>> del classmates[2]
>>> classmates
['Mike', 'SmallXeon', 'Kate', 'Smith']

这样就直接删除了 list 中的成员了。

自带成员函数 remove()

remove() 的操作则更加直接,对指定的成员进行删除,不需要获取下标。而缺点是需要知道完整的成员。

1
2
3
4
5
>>> classmates
['Mike', 'SmallXeon', 'Kate', 'Smith']
>>> classmates.remove('Kate')
>>> classmates
['Mike', 'SmallXeon', 'Smith']

成员函数——栈操作:弹出 pop()

栈是什么又得另说了。
实现弹出操作——即在栈取出顶部元素将其返回,并在栈中删除其。
通过弹出则可以在 list 中实现删除最后一个元素。

1
2
3
4
5
6
>>> classmates
['Mike', 'SmallXeon', 'Smith']
>>> classmates.pop()
'Smith'
>>> classmates
['Mike', 'SmallXeon']

可以看出弹出操作 pop() 是有返回的,即与栈的弹出概念是相同的。

list 的成员类型可以不同

这一点对于 C 的程序员来说十分不可思议,然而 C++ 程序员就比较好接受。因为类模板可以让相同模板类型的成员适应不同的类型。
而此处 Python 的 list 则更加神奇。一个 list 中的成员之间的类型居然也可以不同,这着实令人难以接受。但是反过来看看,是不是可以通过 list 实现简单的结构体呢?(误)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> differentList = ['myName', 21, True, ['student', 'software engine']]
>>> differentList
['myName', 21, True, ['student', 'software engine']]
>>> differentList[1]
21
>>> differentList[3]
['student', 'software engine']
>>> differentList[3][1]
'software engine'
>>>
>>> differentList[3].pop()
'software engine'
>>> differentList
['myName', 21, True, ['student']]

从代码可以看出,list 中还可以嵌套 list 实现二维数组,并且可以直接取出并对内部的 list 进行单独操作,这可以说 Python 这门语言的博大精深了。


这就是 list 的学习简单记录。
明天也要一样加油~

Author: SmallXeon
Link: https://hexo.chensmallx.top/2018/07/03/python-learning-list/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
一些推广链接
几个便宜量大的小✈场: FASTLINK, YToo, 论坛邀请注册: ,
便宜量大但是稳定性不足的VPS: Virmach, 价格略贵但好用的VPN: , ,