首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python进阶之路四-列表

1.列表概述

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

```python

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

```python

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.构建

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

```python

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作为过滤条件.

```python

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.操作

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

```python

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

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

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

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

```

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

```python

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()方法

```python

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

Out[22]: True

```

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

```python

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]

```

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

```python

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.列表排序可以设定条件,比如按照字段或者长度等

```python

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模块,可向有序列表插入元素,它使用二分法查找合适位置,可以实现优先级队列或者一致性哈希算法

```python

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__ 等) 实现自定义排序条件.

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190708A0T61Y00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券