列表是python中用的非常频繁的数据结构,它是有序序列。之前学的字符串就是一种有序序列。不过列表是可变的。
创建列表
li = list( ) #构造方法创建一个空列表
li = list( iterable_Object ) #以其它可迭代对象为参数初始化一个列表
li = [] #快捷方法创建一个空列表
li= [ i for i in range(1,11)] #推导式创建 非常的pythonic :)
if __name__ == "__main__": li0 = [] print(len(li0)) # 0 li1 = list("12345") print("li1 is ",li1) # li1 is [‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘] li2 = list((‘init‘,‘by‘,‘tuple‘)) print("li2 is ",li2) # i2 is [‘init‘, ‘by‘, ‘tuple‘] li3 = [i for i in range(1,11) if i%2==0] print("li3 is ",li3) # li3 is [2, 4, 6, 8, 10] li4 = [(i,j) for i in "abc" for j in "123"] print("li4 is ",li4) #li4 is [(‘a‘, ‘1‘), (‘a‘, ‘2‘), (‘a‘, ‘3‘), (‘b‘, ‘1‘), (‘b‘, ‘2‘), (‘b‘, ‘3‘), (‘c‘, ‘1‘), (‘c‘, ‘2‘), (‘c‘, ‘3‘)]
1、可变的引用类型
可变是值列表对象本身可变。 支持追加,扩展,插入,删除,排序,反转等操作。
2、有序序列
列表是有序的,支持索引读写元素。当然也支持slice,详见我的另一篇随笔
3、元素类型任意
列表中的元素可以是任意类型,包括list类型,而且不同类型可以混合存在。
4、运算符
+
*
in
if __name__ == "__main__": li = [1]+[2,3,4,5] #[1, 2, 3, 4, 5] print(li) li+=[6,7,8] print(li) #[1, 2, 3, 4, 5, 6, 7, 8] li = [1]*3 print(li) #[1, 1, 1] print(1 in li) #True
5、内存模型
列表本身是不包含元素的数据的,而只是包含元素的引用。通过引用,再去访问元素实际指向的对象。
if __name__ == "__main__": a = 100 str = "123" li=[a,str]
再来通过一个深浅拷贝的例子深入说明
if __name__ == "__main__": li = [[1,2],3] li_copy = li.copy(); li_copy[0].pop() print(li) #[[1], 3] 发现副本的变化使源本也改变了 print( id(li[0]) , id(li_copy[0]) ) #1037590501832 1037590501832,一样的地址
第一张图中我们说列表中保存的只是元素的引用而已,这个引用,换个说法就是指针。通过copy方法拷贝的是列表中的元素,也就是引用,同样也是地址。
上图中 li[0] 本身的值是 1037590501832 通过copy方法后,li_copy[0]也获得了li[0]本身的值,所以他也指向列表中的那个嵌套的小列表。
so,通过li_copy来改变那个嵌套的小列表,会反映到li中。
如果需要避免这个情况,我们可以使用深拷贝。
#/usr/bin/env python3 # coding:utf-8 import copy if __name__ == "__main__": li = [[1,2],3] li_copy = copy.deepcopy(li) li_copy[0].pop() print(li) #[[1, 2], 3] 发现副本的变没有让源本改变 print( id(li[0]) , id(li_copy[0]) ) #1046997603464 1046997603528 地址不一样
6、常用API
li.append("1") #追加字符串"1"
li.extend([1,2,3]) #扩张列表,追加多个 ,等效于li +=[1,2,3]
li.insert(3,"hello") #插入
li.pop() #弹出最后一个元素
li.pop(1) #删除索引为1的 元素
li.remove(val) #根据值删除
li.index(val) #返回val元素的索引 没找到 则报错
li.sort() #排序,要求元素之间能比较。原地排序
sorted(li) #返回排序拷贝份,非原地排序