列表是python的内置可变序列,对python列表的操作也是基于值得自动内存管理机制,即如果对一列表得行内元素进行删除或者扩展,那么python会对列表对象进行扩张或者收缩,从而保证元素在内存种没有间隔。
列表的创建
列表得创建有三种方式
- 通过赋值直接创建 a=[]
- 通过list方法进行数据类型转换a=list((1,2,3,5))
- 通过range([start,]stop[,step])方法进行创建
列表元素的增加
列表元素得增加分为两个方向得增加,第一个方向是变成新的内存地址得对列表;第二个方法是在原来列表得内存地址上进行增加,后者得方式是真正的增加。不改变列表的内存地址,也符合列表的可变序列的特质。现在来说明如何实现这两种方式的列表增加;
增加后变成新的内存地址的列表
- “”,使用"”运算符,能够实现原列表的重复;
- “+”,使用 "+"运算符[1,2]+[3,4]
真正意义上的增加,使用列表的属性
- insert属性,list.insert(index,data),将data数据加入到list中的index下标的地方;
- extend属性,list1.extend(list2),将list2中的全部元素加到list1列表中;
- append属性,list.append(data);将data数据加入list列表中的末尾;
列表元素的删除
列表元素的删除,分为两种方式的删除;关键字删除和列表属性删除。 关键字删除 就是使用del
del list[1]
列表属性的删除
- pop(),删除列表中的最后一个值,并返回这个值。
- remove()方法,用于移除列表中某个值的第一个匹配项。
基于值的内存自动管理与列表
python基于值的内存自动内存管理对于列表元素的增加和删除有一些影响。
对于增加
由于是基于值得内存自动管理,所以在列表中间增加一个值,会导致这个下标后面得值,全部向后移动,会导致大大的增加内存的消耗和时间的消耗。所以对于列表元素的增加,最好是增加到列表的末尾,这样子可以大幅度提高程序的运行时间
import time
start1=time.time()
a=list(range(1,100000000))
a.insert(2,10)
start2=time.time()
a.append(10)
start3=time.time()
print(start2-start1)
print(start3-start2)
# 运行结果
# 第一个输出是2.2665457725524902,第二个输出是0.0
可以看出效率的差别了。所以对列表的增加删减工作最好是从列表末尾开始
对于删除
其实对于增加还是可以的,只是时间和内存的增加。但是删减的话,反而会报错。来看下面的两段代码,就指出了这个问题
a=[1,1,2,3,4,5]
for i in a:
if i==1:
a.remove(i)
print(a)
最后的结果确是[1,2,3,4,5].还有下面第二段代码
x=[1,2,1,2,1,1,1]
for x in range(len(x)):
if x[i]==1:
del x[i]
这段代码运行后会报错。“list index out of range”
上面的两个问题都是由python的基于值得内存自动管理系统造成得,即python删除元素后会先自动进行内存管理,保证列表中的元素中间没有空隙,才会接着执行python代码。导致了。所以删除元素必须要求从后向前删除。
列表元素的访问与计数
列表的访问方式
- 使用列表的方法,index(),list.index(object),加入索引,返回这个object元素首次出现的位置的下标,如果列表中无该元素则会报错。
- 使用切片方式,切片方式也是对列表的浅层赋值即list[start,stop,step]。
- 列表元素的计数,使用count(object),就能够知道object元素在该列表中出现了几次。
成员资格判断
即是用"in"与“not in"的运算符。
切片
列表的切片不会因为下标越界而抛出异常,而是简单的在列表的尾部截断或者放回一个空列表(如果切片出来的区域没有列表元素的话)
切片的使用方式也很简单,只要在切片中增加三个数,即可切得到一块区域。[start,stop,step].切片是浅层复制,即再切片获取到的是一个新的列表,比如看下面这段代码
>>> x=[1,2,3]
>>> id(x) # 第一处
2961803576200
>>> x=x
>>> id(x) # 第二处
2961803576200
>>> x=x[::]
>>> id(x) # 第三处
2961803593800
可以看出上面的第一处和第二处相同(列表的深层复制)第二处和第三处相同(列表的浅层复制)
列表排序
列表排序这里来说明排序的两种方式,第一种是列表的方法sort()排序,第二种是python的内置函数sorted排序
列表的方法排序
list.sort()使用方式很简单,但是使用方式也很单调,只有一个关键字list.sort(reverse=True)来进行倒置排序,比如从大到小。
python的内置函数sorted
sorted(iterable, *, key=None, reverse=False)现在来说明一下这三个
- iterable可迭代对象
- reverse是否倒置
- key是关键字,这个是一个函数,这个函数的特别之处就是放入的是可迭代对象中的元素,返回的是元素中的一个部分,最好的就是使用匿名函数lamble。下面来举一个例子,
# 按照item的第二个元素从大到小排序
item1=(1,2,3)
item2=(1,1,3)
item3=(1,4,3)
item4=(1,5,3)
li=[item1,item2,item3,item4]
ans=sorted(li,key=lambda x :x[1] , reverse=True)
print(ans)
运算的结果:[(1, 5, 3), (1, 4, 3), (1, 2, 3), (1, 1, 3)]
用于序列操作的常用内置函数
zip()内置函数,使用方式,如:zip(list1,list2,list3),将多个列表或者元组对应位置的元素组合成元组(这个就要求了每个列表都应该具有相同的长度),并返回包含这些元组的列表,下面举一个例子。
>>> list1=[1,2,3,4,5]
>>> list2=[5,4,3,2,1]
>>> list3=[0,9,8,7,6]
>>> list4=zip(list1,list2,list3)
>>> list4
<zip object at 0x00000225D45D63C8>
>>> list(list4)
[(1, 5, 0), (2, 4, 9), (3, 3, 8), (4, 2, 7), (5, 1, 6)]
enumerate()内置函数,这个函数迭代序列,返回一个元组,这个二元元组,第二个元素是是这个迭代出来的数据,第一个元素,就是这个元素所在的下标。下面举一个例子。
>>> list=['a','b','c','d','e','f']
>>> for item in enumerate(list):
... print(item)
...
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')
(5, 'f')
map(),这个函数需要两个参数,即map(function,Iterable),这个函数的作用是什么,就是将可迭代数据进行一一的map,function需要注意的有两点,第一点必须有一个参数,第二点,必须返回一个数据。下面来举例一个。
>>> def f(x):
... return x * x
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
>>>
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
filter()内置函数,filter()函数用于过滤序列。接收的函数与map一样也是一个函数和一个序列。不过这个函数有一点特别之处就是返回的数据要是布尔类型,即把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。下面有一个例子
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
列表生成器
list=[x for x in iterable],
现在来讲一下列表生成器的比较有趣的用法。
>>> a=["1-2","2-3","3-4","4-5"]
>>> b=[x.replace('-','') for x in a]
>>> b
['12', '23', '34', '45']
这个有点类似python的内置函数map.
>>> a=[1,21,3,1,2,321,31,3,1211,3,31,3,1,1]
>>> b=[x for x in a if x >19]
>>> b
[21, 321, 31, 1211, 31]
这个就是将if加到了列表生成器中
>>> x=[1,2,3,4]
>>> y=[2,3,4,5]
>>> [(a,b) for a in x for b in y]
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 3), (3, 4), (3, 5), (4, 2), (4, 3), (4, 4), (4, 5)]
经过了上面的三个例子,我们可以来归纳一下列表生成器。
[元素 for for for 。。。多重循环 条件语句 过滤]
列表的常用方法
列表的常用方法 | 说明 |
---|---|
list.append(x) | 在列表末尾添加x |
list.extend(L) | 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
list.insert(index, obj) | 将对象插入列表 |
list.remove(obj) | 移除列表中某个值的第一个匹配项 |
list.pop([index=-1]) | obj – 可选参数,要移除列表元素的索引值,不能超过列表总长度,默认为 index=-1,删除最后一个列表值。 |
list.index(obj) | 从列表中找出某个值第一个匹配项的索引位置 |
list.count(obj) | 统计某个元素在列表中出现的次数 |
list.reverse() | 反向列表中元素 |
list.copy() | 浅层复制 |