1、通用序列操作
Python中所有序列都可以进行一些特定操作,包括索引(indexing)、分片(slicing)、序列相加(adding)、乘法(multiplying)、成员资格、长度、最小值和最大值。
1)索引
序列是Python中最基本的数据结构。序列中的每一个元素都分配一个数字,代表它在序列中的位置(索引),第一个索引是0,第二个索引是1,以此类推。
这里的编号就是索引,可以通过索引获取元素。所有序列都可以通过这种方式进行索引。
在Python中,从左向右索引称为正数索引,从右向左索引称为负数索引。使用负数索引时,Python会从最后一个元素开始计数。最后一个元素的位置编号是-1。
2)分片
索引用来对单个元素进行访问,使用分片可以对一定范围内的元素进行访问,分片通过冒号相隔的两个索引实现。
分片操作的实现需要提供两个索引作为边界,第一个索引的元素包括在分片内,第二个索引的元素不包括在分片内。想数学里的a<=x<b,x是我们需要得到的元素,a是分片操作中的第一个索引,b是第二个索引,b不包含在x的范围内。如果在分片中最左边的索引比它右边的索引晚出现在序列中,结果就是一个空序列。如果需要取得的分片包括序列结尾的元素,只需将第二个索引设置为空即可。Python为我们提供了另一个参数 – 步长,该参数通常是隐式设置的。
对于正数步长,Python会从序列的头部开始向右提取元素,直到最后一个元素;对于负数步长,则是从序列的尾部开始向左提取元素,直到第一个元素。正数步长必须让开始点小于结束点,而负数步长必须让开始点大于结束点。
3)常用函数和方法
函数 | 描述 |
---|---|
+ | 使用加号可以进行序列的连接操作,原序列内容没有改变,数字序列可以和数字序列通过加号连接,连接后的结果还是数字序列;字符串序列也可以通过加号连接,连接后的结果还是字符串序列;数字序列和字符串序列不能通过加号连接 |
* | 一个数x乘以一个序列会生成新的序列,原来的序列将被重复x次 |
s[i] | 访问指定下标元素 |
s[i:j] | 访问指定范围元素 |
s[i:j:k] | |
in | 检测字符或数字是否在对应的列表中,返回值为True或False,数字类型不能再字符串类型中通过in进行成员资格检测,而字符串类型可以在数字列表中通过in进行成员资格检测 |
not in | 判断成员不在序列中 |
len() | 求序列中的长度,并将之返回 PS:从1开始计数,没有计算结束标志位 |
min() | 求序列中的最小值,并将之返回(ASCII顺序) |
max() | 求序列中的最大值,并将之返回(ASCII顺序) |
sum() | 统计求和 |
.index() | 检索元素第一次出现下标 |
.count() | 统计元素出现的次数 |
del | obj 删除对象 或对象中的元素 |
注:
虽然从名称上看,del语句代表的是删除,但是实际上del语句的作用并不一定是删除数据。应用于某些对象引用(引用的是非组合类型的数据项)时,del语句的作用是取消该对象引用到数据项的绑定,并删除对象引用。
对象引用被删除后,如果该对象引用所引用的数据项没有被其他对象引用进行引用,那么该数据项将进入垃圾收集流程。
用于组合数据类型(列表或元组)时,del语句删除的只是对组合类型的对象引用。如果该对象引用所引用的组合类型数据没有被其他对象引用进行引用,那么该组合类型数据及其项(对于本身也是组合类型的项进行递归处理)将进入垃圾收集流程。
对于可变的组合数据类型,比如列表,del可应用于单个数据项或其中的数据片 — 两种情况都需要使用分片操作符 [ ]。如果引用的单个或多个数据项从组合类型数据中移除,并且没有其他对象引用对其进行引用,就进入垃圾收集流程。
2、列表 list[ ]
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
- 可包含任意对象的有序集合
- 通过下标索引(位置偏移)访问元素
- 可变长度,异质,客人已嵌套
- 支持原位改变
- 对象引用数组
序列都可以进行的操作包括索引,切片,加,乘,检查成员。
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。列表的数据项不需要具有相同的类型,创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。
1)更新列表
有关序列的操作,如:索引、分片、相加、乘法等都适用于列表,而下面介绍的适用于列表不适用于序列,这些方法的作用都是更新列表。
元素赋值 | 描述 |
---|---|
赋值说明 | 可以通过编号标记某个特定位置的元素,并对该位置的元素重新赋值;并且可以对一个列表的元素赋不同类型的值;不能超出列表的范围赋值,即不能为一个不存在元素的位置赋值; |
分片赋值 | list()函数可以直接将字符串转化为列表;该函数的一个功能就是根据字符串创建列表,有时这么操作会很方便。List()函数不仅适用于字符串,所有类型的序列它都适用; |
改变某个位置元素 | list[i]=x |
改变特定范围内元素 |
s[i,j]=[] 新替换的对象必须为可迭代序列;替换的序列将替换的元素删除之后替换,即被替换的范围元素全部删除,增加新元素;新增元素个数可小于、等于或大于替换元素个数;s[i,j,k]=[] 有步长时,新替换的元素必须为可迭序列;替换元素个数必须和被替换元素的个数保持一致; |
2)删除元素
方法 | 描述 |
---|---|
del list | 删除列表 |
del list[i] | 删除某个特定元素 |
del list[i:] | 删除指定范围元素 |
del list[i:j:k] | 删除指定范围元素,带步长 |
list[:j]=[] | 赋空值等同于删除指定范围元素 |
list[i:j:k]=[]*x | 带步长赋值空时,个数x一定要和替换个数保持一致 |
list.remove(x) | 删除第一个匹配值 |
list.clear() | 清空序列,序列为空:[] |
3)嵌套和多维列表
在列表中可以嵌套列表,嵌套的列表取出后还是列表。
>>>field=[‘a’,‘b’,‘c’]
>>>num=[1,2,3]
>>>mix=[field,num]
[[‘a’,‘b’,‘c’],[ 1,2,3]]
b_list = [[1,2,3],
[4,5,6],
[7,8,9]]
print(b_list[1])
[4,5,6]
print(b_list[2][1])
8
4)列表函数和方法
方法是与对象有紧密联系的函数,对象可能是列表、数字,也可能是字符串或其他类型的对象。方法的调用格式:
对象.方法(参数)
方法的定义方式是将对象放到方法名之前,两者之间用一个点号隔开,方法后面的括号中可以根据需要带上参数。
列表方法 | 描述 |
---|---|
append() | 用于在列表末尾添加新对象的方法。功能是在列表的末尾添加新对象 |
extend() | 多用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表);extend()方法和序列相加的主要区别是:extend()方法修改了被扩展的序列,原始的连接操作会返回一个全新的列表,返回的是一个包含list和seq副本的新列表,而不会修改原始的变量。 |
insert() | 用于在列表index索引位置插入新元素obj |
count() | 用于统计某个元素在列表中出现的次数 |
index() | 用于从列表中找出某个值第一个匹配项的索引位置 |
pop() | pop()方法用于移除列表中的一个元素(不传参数时,默认为最后一个元素),并返回该元素的值;pop()方法是唯一一个既能修改列表又能返回元素值(除None)的列表方法。使用pop方法可以实现一种常见的数据结构—栈。栈的原理就像堆放盘子一样,一次操作一个盘子,要将若干个盘子堆成一堆,只能在一个盘子的上面放另一个盘子;要拿盘子时,只能从顶部一个一个往下拿,最后放入的盘子时最先被拿的。栈也是如此,最后放入栈的最先被移除,称为LIFO(last in first out),即后进先出。 栈中的放入和移除操作有统一称谓 ---- 入栈(push)和出栈(pop)。Python没有入栈方法,但可以使用append方法替代,pop方法和append方法的操作结果恰好相反,如果入栈(或追加)刚刚出栈的值,最后得到的结果就不会变 |
remove() | 用于移除列表中某个值的第一个匹配项 ,remove方法是一个没有返回值得原位置元素变更方法,它修改了列表却没有返回值,与pop方法正好相反 |
clear() | clear()方法用于清空列表,类似于del a[:],clear()方法会清空整个列表,调用该方法进行清空很简单,但也要小心,因为一不小心就可能把整个列表都清空。 |
5)复制与排序
函数 | 描述 |
---|---|
copy() | 等同于list_c = list[:] 如果使用赋值 list_c = list 则会出现共享引用,copy()方法用于赋值列表,类似于 a[:]。简单的使用等号 (=)复制,会出现共享引用,为了避免共享引用,可以采取list.copy()方法或者list_c = list[:]。此语法中list不需要传入参数 |
reverse() | reverse()方法用于反向列表中的元素。此语法不需要传入参数,且该方法改变了列表但不返回值,此方法只删除第一个匹配值。如果需要对一个序列进行反向迭代,那么可以使用reverse方法,这个方法并不返回列表,而是返回一个迭代器对象,可以通过list函数把返回的对象转换为列表 |
sort() | list.sort(key = None , reverse =False) 默认从小到大排序。sort()方法用于对原列表进行排序,指定参数,就使用参数指定的比较方法进行排序;sort()方法有两个可选参数,即key和reverse。参数key,参数reverse默认False时为从小到大排序,reverse=True时,则为从大到小排序。注:当用户需要一个排好序的列表副本,同时又保留原有列表不变时 |
sorted() | list_n = sorted(list)如reverse()方法一样,sort()方法也有一个同样功能的函数 ---- sorted()函数;该函数可以直接获取列表的副本进行排序。sorted()方法可以用于任何序列,返回结果都是一个列表 |
6)将列表当做堆栈使用
列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如:
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
7)将列表当作队列使用
也可以把列表当做队列用,只是在队列里第一加入的元素,第一个取出来;但是拿列表用作这样的目的效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)。
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
8)列表推导式
列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。
每个列表推导式都在 for 之后跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。
这里我们将列表中每个数值乘三,获得一个新的列表:
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]
现在我们玩一点小花样:
>>> [[x, x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]
这里我们对序列里每一个元素逐个调用某方法:
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
我们可以用 if 子句作为过滤器:
>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]
以下是一些关于循环和其它技巧的演示:
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]
列表推导式可以使用复杂表达式或嵌套函数:
>>> [str(round(355/113, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
3、元组 tuple()
Python的元组和列表类似,不同之处在于元组的元素不能修改(前面提过的字符串也是不能修改的)。元组一旦初试换就不能修改,元组只能从新赋值时才可以修改。不可变的元组有什么意义?因为元组不可变,所以代码更安全。
- 可包含任意类型的有序集合
- 固定长度,异质
- 可任意嵌套
- 通过下标索引(位置偏移)访问元素
- 对象引用数组
1)创建元组##
元组也可以使用tuple()函数创建,空元祖是使用圆括号()创建的,包含一个或多个项的元组则可以使用逗号分隔进行创建。
创建元组的方法很简单:使用逗号分隔一些值,就会自动创建元组。
>>>(1,2,3)
(1,2,3)
>>>(‘hello’ , ‘world’)
(‘hello’ , ‘wor`这里写代`这里写代码片`码片`ld’)
>>>()
()
>>>(1) #错误,结果不是元组
(1)`这里写代码片
>>>(1,) #正确,结果是元组
(1,)
还可以使用圆括号将值括起来,以及创建空元祖,圆括号不包含任何内容,就是一个空元祖,创建一个值得元组时,必须在括号中的元素后加上一个逗号
当元组只有一个元素的时候,必须注意在该元素结尾加上 “,”,以区分变量。
内置函数 | 描述 |
---|---|
tuple() | tuple()函数的功能和list()函数基本上一样,都是以一个序列作为参数,并把它转换为元组。如果参数是元组,参数就会被原样返回 |
tuple(list) | 用于将列表转换为元组 |
2)访问元组
可以使用下标索引访问元祖中的值
>>>mix = (‘hello’ , ‘world’ , 2015 ,2016)
>>>print(“mix [1] is:”, mix[1])
mix [1] is: world
>>>num = (1,2,3,4,5,6,7)
>>>print(“num [1:5] is :” , num[1:5])
num[1:5] is : (2,3,4,5)
3)修改元组
>>>field = ('hello’ , ‘world’)
>>>num = (2015,2016)
>>>print(“合并结果为:” , field + num)
合并结果为:('hello’ , ‘world’ , 2015,2016)
元组中的元素不允许修改,但可以对元组进行连接组合。
4)删除元祖
>>>field =(‘hello’ , ‘world’)
>>>del field
>>>print(‘删除后的结果:’ , field)
Traceback (most recent call last):
Field “<pyshell#84>”,line 1,in <module>
print(‘删除后的结果:’, field)
NameError : name ‘field’ is not deefined
元组中的元素值不允许删除,但可以使用del语句删除整个元组。元祖被删除后,输出变量会有异常信息,输出结果显示没有定义field,即field已经不存在了。
5)元祖索引、截取
因为元组也是一个序列,所以可以访问元祖中指定位置的元素,也可以截取索引中的一段元素。
>>>field = (‘hello’ , ‘world’ , ‘welcome’)
>>>field[2]
‘welcome’
>>>[-2]
‘world’
>>>field[1:]
(‘world’ , ‘welcome’)
4、range
Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。
range()一般生成数值序列,以便执行待定次数的循环,类型为range类型。
同元组一样,不支持原位改变。
Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。
函数语法
range(stop)
range(start,stop, [step])
参数说明:
start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)