我是靠谱客的博主 甜美电话,最近开发中收集的这篇文章主要介绍python进阶学习(一)数据结构--列表前言数组,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

前言

数组

列表

列表推导式与高阶函数

生成器表达式

当列表不够用时

双向队列

元组

元组与记录

具名元组nametuple

作为不可变列表


前言

本篇以及接下来的篇章均为《流畅的python》学习笔记,内容主要出自该书,重点偏向于应用

这节主要展示python数据结构的特性,以及使用自带的collections模块来方便地解决一些实际的问题

collections是python的一个标准库,这个模块实现专门的容器数据类型,提供Python的通用内置容器,字典,列表,集和元组的替代方法

数组

列表

既然叫做进阶学习,那么列表的基本操作不会再次描述

列表推导式与高阶函数

现有一个需求,筛选出列表中大于0的元素

最简单的想法当然是遍历一遍啦

lis = [-2,1,4,6,-4,0,2,5]

result = []
for i in lis:
    if i > 0:
        result.append(i)
        
print(result)

也可以用列表推导式,列表推导式其实就是一种生成列表的快捷方法,可以增加代码可读性,for in表示迭代的列表,if后面写上条件

lis = [-2,1,4,6,-4,0,2,5]

[x for x in lis if x>0]

用高阶函数也是可以的

lis = [-2,1,4,6,-4,0,2,5]

list(filter(lambda x: x>0, lis))

那么用列表推导式和高阶函数哪一个快一点呢?答案是不一定,一般用列表推导式,不过它们俩都比迭代更好。

字典,集合数据结构和列表一样都有相应的推导式,在需要的时候也可以使用。

生成器表达式

生成器表达式和列表推导语法差不多,只不过把外面的中括号改成小括号。

生成器表达式构建生成器,可以通过迭代逐个构建元素,所以使用生成器可以节省内存。

当列表不够用时

其实,python中除了list以外还有很多数据结构可以帮助我们存储数组,例如tuple,collections.deque,也可以去下载额外的库,当需要处理大规模数组类型或者需要高阶的数据处理用法时,可以使用NumPy和SciPy

双向队列

因为列表有pop和append方法,所以把列表当成先进先出的队列来用也是可以的,不过,频繁删除或插入位于第一个位置的元素效率并不高,因为会涉及整个列表数据的移动,这时候就可以使用双向队列。

collections包中实现的双向队列,是一个线程安全、可以快速从两端添加和而删除元素的数据类型。

from collections import deque

dq = deque(range(10))

# deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

dq.popleft()

# deque([1, 2, 3, 4, 5, 6, 7, 8, 9])

dq.appendleft(10)

# deque([10, 1, 2, 3, 4, 5, 6, 7, 8, 9])

双向队列只对队列两端的操作做了优化,相应的,队列中间的元素操作会慢一些。

元组

元组与记录

元组在python中一般都是用作不可变列表,但是它还有另一个功能,就是作为无名字段的记录。

在元组用作数据记录时,元组中每个元素都存放了记录中一个字段的数据,外加上这个字段的位置。作为记录来说,元组的位置信息就变得非常重要了。

我们可以用下面的方式来记录一个用户的id,name,email和password

user1 = ('1', 'Alice', '123@164.com', '123456')

是不是很像一个数据库的记录了呢? 

并且python的拆包功能能够让元组更加方便地当成记录来使用

In [3]: id, name, email, password = ('2', 'Tom', '1234@163.com', '123456')

In [4]: user2 = (id, name, email, password)

比如,一个网站想要存储用户的id,用户名,邮箱和密码,就可以采用元组的形式进行存放,如果我们想要获取其中的数据,我们需要这样:

In [2]: User[1]
Out[2]: 'Alice'

具名元组nametuple

可以看到,元组可以采用数字来获取元组中某个字段的值,但是这样子写明显存在很多的问题,一旦字段一多,代码里全是各种数字检索值,无法一眼看出这个引用所代表的含义,这样的程序就很难维护和阅读。

一般可以想到的方法是,把字段的名称以及对应的字段位置用常量的方式来定义

ID = 0
NAME = 1
EMAIL = 2
PASSWORD = 3

这样一来如果要取值的话只需:

In [2]: User[NAME]
Out[2]: 'Alice'

可读性是不是好点啦?

 

不过我们也可以使用具名元组nametuple来解决问题,它可以构建一个带有字段名的元组和一个有名字的类

使用方法:

collections.namedtuple(typenamefield_names*verbose=Falserename=Falsemodule=None)

第一个参数设定这个类的名字,第二个参数可以传入字段名的列表

In [5]: from collections import namedtuple

In [6]: User = namedtuple('User', ['id', 'name', 'email', 'password'])

可以看到,nametuple就是一个工厂函数,作用就相当于创建一个类

这种做法是不是和构建一个类来存放记录数据差不多?的确,不过由nametuple构建的类的实例比普通类构建的实例消耗的内存更小,因为普通的类需要使用__dict__来存放类实例的属性,而nametuple构建的类则不需要,且实例所消耗的内存和元组是一样的,因为字段名是存放在对应的类里面。

我们可以使用类的创建方式来创建一组数据

In [7]: u1 = User('3', 'Bob', '123456@163.com', '123456')

In [8]: u1
Out[8]: User(id='3', name='Bob', email='123456@163.com', password='123456')

同时,我们可以使用获取类属性的方式来获取数据,这样使用非常的方便

In [9]: u1.id
Out[9]: '3'

In [10]: u1.email
Out[10]: '123456@163.com'

另外,我们可以看到,创建出来的类也是tuple的子类,也就是说,任何可以使用元组的地方,我们也可以使用nametuple来代替

In [11]: isinstance(u1 ,tuple)
Out[11]: True

作为不可变列表

元组当然也可以当做不可变列表来用,除了增减元素的方法外,元组支持列表的其他所有方法。

 


下一篇:python进阶学习(二)数据结构--字典和集合

最后

以上就是甜美电话为你收集整理的python进阶学习(一)数据结构--列表前言数组的全部内容,希望文章能够帮你解决python进阶学习(一)数据结构--列表前言数组所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部