美文网首页
Python进阶之路(四)列表

Python进阶之路(四)列表

作者: EchoPython | 来源:发表于2019-07-08 21:42 被阅读0次

1.列表概述

仅仅从操作方式上看,列表像是数组和链表的结合体,除按照索引访问外,还支持插入,追加,删除等操作.完全可当做队列或者栈进行使用.如果不考虑性能问题,列表视乎是一种易用且功能完善的理想数据结构.

In [1]: x= [1, 2]                                                                                                                                                                            

In [2]: x[1]                                                                                                                                                                                 
Out[2]: 2

In [3]: x.insert(0,0)      # 插入数据                                                                                                                                                                 

In [4]: x                                                                                                                                                                                    
Out[4]: [0, 1, 2]

In [5]: x.reverse()     # 反转                                                                                                                                                                     

In [6]: x                                                                                                                                                                                    
Out[6]: [2, 1, 0]

queue

In [7]: q = []                                                                                                                                                                               

In [8]: q.append(1)           # 在列表最后插入一个数据                                                                                                                                                               

In [9]: q.append(2)                                                                                                                                                                          

In [10]: q                                                                                                                                                                                   
Out[10]: [1, 2]

In [11]: q.pop()                # 清除追加顺序弹出数据                                                                                                                                                            
Out[11]: 2

In [12]: q.pop()                                                                                                                                                                             
Out[12]: 1

In [13]: q                                                                                                                                                                                   
Out[13]: []

如果有大量写操作,建议使用 collections,queue 类型


列表的内部结构是由两部分组成,保存元素数量和内存分配计数的头部,以及储存元素指针的独立数组.所有元素项使用该数组保存指针引用,并不嵌入内容.


在这里插入图片描述

作为使用频率最高的数据结构之一,列表的性能优化很重要,固定长度的头部结构,很容易实现内存复用.创建时,有限从复用区获取.被挥手时,除非超出复用数量限制(80) ,否则会被放回服用去,而非交还内存,每次真正需要分配和释放的是指针数组.

用数组而非链表存储元素项引用,也有实际考虑.从读操作开看,无论遍历还是基于序号访问,数组性能总是最高的.尽管插入,删除,等变更操作需要移动内存,但也仅仅是指针复制,无论元素大小,不会有太高消耗,如果列表太大,或者写操作多余读,那么应该使用针对性的数据结构操作.


2.构建

显示指定元素构建语法最为常用,也可基于创建类型,接受可迭代对象作为初始内容,不同于数组,列表仅存储指针,而对元素内容毫不关心,如此,可以是不同类型混合.

In [14]: [1,"abc",3.14]                                                                                                                                                                      
Out[14]: [1, 'abc', 3.14]

In [16]: list("abc")                                                                                                                                                                         
Out[16]: ['a', 'b', 'c']

In [17]: list(range(3))                                                                                                                                                                      
Out[17]: [0, 1, 2]

另外有被称之为列表推导式的语法,同样适用括号,但是以for循环初始化元素,并且可以选择if作为过滤条件.

In [1]: class A(list): 
   ...:     pass 
   ...:                                                                                                                                                                                      

In [2]: type(A('abc')+ list('del'))       # 返回的是list而不是a                                                                                                                                                
Out[2]: list

In [3]: class B(collections.UserList): 
   ...:     pass 
In [4]: type(B("abc") + list("del"))       # 返回了B类型                                                                                                                                                  
Out[4]: __main__.B


最小接口设计是一个基本原则,应该慎重考虑这种功能的类型是否适合作为基类.

3.操作

用加法运算符链接多个列表,乘法赋值内容

In [9]: [1, 2] + [3, 4]                                                                                                                                                                      
Out[9]: [1, 2, 3, 4]

In [10]: [1, 2] * 2                                                                                                                                                                          
Out[10]: [1, 2, 1, 2]

注意,同时加法(或者减法) 运算,但是结果可能会不同.

In [12]: a = [1, 2]                                                                                                                                                                          

In [13]: b = a                                                                                                                                                                               

In [14]: a = a + [3, 4]                   # 新建列表对象,然后和a关联                                                                                                                                                   

In [15]: a                                                                                                                                                                                   
Out[15]: [1, 2, 3, 4]                    # a,b结果不同,确定a指向新对象

In [16]: b                                                                                                                                                                                   
Out[16]: [1, 2]

In [17]: a = [1, 2]                                                                                                                                                                          

In [18]: b = a                                                                                                                                                                               

In [19]: a += [3, 4]                      # 直接修改了a的内容                                                                                                                                         

In [20]: a                                                                                                                                                                                   
Out[20]: [1, 2, 3, 4]

In [21]: b                                 #  b的内容也随着更改                                                                                                            
Out[21]: [1, 2, 3, 4]

编译器将"+=" 运算符处理成INPLACE_ADD操作,也就是修改原函数,而并非建立新对象,其中效果类似于list.extend 方法

判断元素是否存在,习惯用in,而并非index()方法

in[22]: 2 in [1, 2]                                                                                                                                                                         
Out[22]: True

至于删除操作,可用索引序号指定单个元素,或者切片指定删除范围.

In [23]: a = [0, 1, 2, 3, 4, 5]                                                                                                                                                              

In [24]: del a[5]           # 删除单个元素                                                                                                                                                                 

In [25]: a                                                                                                                                                                                   
Out[25]: [0, 1, 2, 3, 4]

In [26]: del a[1:2]            # 删除范围元素                                                                                                                                                              

In [27]: a                                                                                                                                                                                   
Out[27]: [0, 2, 3, 4]

返回切片时创建新列表对象,并且复制相关指针数据到新数组,出所引用目标相同之外,列表自身的修改(增加,删除) 互不影响

In [32]: a = [0, 2, 4 ,6]                                                                                                                                                                    

In [33]: b = a[:2]                   # 复制引用                                                                                                                                                        

In [34]: b                                                                                                                                                                                   
Out[34]: [0, 2]

In [35]: a[0] is b[0]                                                                                                                                                                        
Out[35]: True

In [36]: a.insert(1,1)             # 对a列表操作,不会影响b                                                                                                                                                          

In [37]: a                                                                                                                                                                                   
Out[37]: [0, 1, 2, 4, 6]

In [38]: b                                                                                                                                                                                   
Out[38]: [0, 2]

复制的是指针(引用),而并非目标元素对象.
对列表自身的修改互补影响,但是对目标元素对象的修改是共享的


3.列表排序可以设定条件,比如按照字段或者长度等

In [55]: d = [3,0,2,1]                                                                                                                                                                       

In [56]: sorted(d)             # 同样可以指定排序条件,或者倒叙                                                                                                                                                              
Out[56]: [0, 1, 2, 3]

In [57]: d                                                                                                                                                                                   
Out[57]: [3, 0, 2, 1]

4.利用bisect模块,可向有序列表插入元素,它使用二分法查找合适位置,可以实现优先级队列或者一致性哈希算法

                                                                                                                                                                        
In [59]: import bisect                                                                                                                                                                       

In [60]: bisect.insort_left(d,1)          # 插入新的元素后,依旧保持有序状态                                                                                                                                                   

In [61]: d                                                                                                                                                                                   
Out[61]: [0, 1, 2, 4]

In [62]: bisect.insort_left(d,2)                                                                                                                                                             

In [63]: d                                                                                                                                                                                   
Out[63]: [0, 1, 2, 2, 4]

In [64]: bisect.insort_left(d,3)                                                                                                                                                             

In [65]: d                                                                                                                                                                                   
Out[65]: [0, 1, 2, 2, 3, 4]


自定义复合类型,可通过重载比较运算符(eq,lt 等) 实现自定义排序条件.

相关文章

网友评论

      本文标题:Python进阶之路(四)列表

      本文链接:https://www.haomeiwen.com/subject/rwrzhctx.html