资讯专栏INFORMATION COLUMN

Python奇遇记:数据结构窥探

mrli2016 / 843人阅读

摘要:挤掉了堆中实现了堆排序。你可以用堆排序来查找一个序列中最大的或者最小的几个元素。除了使用堆排序,中还有排序和,这两个排序最终生成以列表表示的排序结果,堆排序也是。

这次我们来说说python中的数据结构。当然了,不会讲很基础的内容。

用过python的都知道,python有着与其他语言很不一样的数据类型,像什么列表、元组、集合、字典之类。这些数据类型造就了python简单易用同时又很强大的特性。一般来说,我们会将python中的数据类型分为可变和不可变类型,可变的意思就是你可以修改像列表中的数据,不可变当然就是不能修改啦。还有一种分法是分为扁平类型和容器类型,其中扁平类型存放的是实际的值,包括str, bytes, bytearray,array.array这些,而容器类型存放的是数据值的引用,包括list,tuple,collections.deque这些。

既然是讲数据结构,我们来看看python中不经常用到的一些数据类型。

数组

没错,python是有数组类型的。当你有很大的数据需要处理的时候,它比列表更高效。如何创建一个数组?使用array.array。比如我们创建一万个随机浮点数。

from array import array

from random import  random
# array中的第一个参数代表数据类型,比如float,char等。第二个参数为可迭代的数据。
# d代表双精度浮点类型
data = array("d", (random() for i in range(10**7)))
# 输出最后一个元素看看
print(data[-1])
0.5888905969627429

数组中提供了一些很有用的方法来处理数据,比如pop,insert,同时也有写入文件的tofile和读取的frombytes方法。

with open("data.bin", "wb") as fp:
    data.tofile(fp)
双端队列

学过数据结构的都知道队列,双端队列就是两边都可以进出的队列。python中的双端队列使用collections.deque表示。当然了你如果想用它来表示栈也是没问题的。append方法用来添加,pop方法用来弹出。怎么使用?

from collections import deque
data = deque(range(10), maxlen = 3)
print(data)
deque([7, 8, 9], maxlen=3)

如上所示,第一个参数为数据,第二个参数是队列的最大长度,如果不指定则默认为无限长。如果限制了长度,则增加数据会挤掉最先插入的数据。

data.append(3)
# 挤掉了7
print(data)
data.pop()
print(data)
deque([8, 9, 3], maxlen=3)
deque([8, 9], maxlen=3)

python中实现了堆排序。你可以用堆排序来查找一个序列中最大的或者最小的几个元素。比如我们有一个列表:

import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]

# 找出最大的几个
print(heapq.nlargest(3, nums)) # Prints [42, 37, 23]
# 找出最小的几个
print(heapq.nsmallest(3, nums)) # Prints [-4, 1, 2]
[42, 37, 23]
[-4, 1, 2]

使用nlargest可以找出最大的几个元素,相反的nsmalllest找最小的几个元素。如果需要找的是字典类型呢?还有第三个参数key,指定我们对数据进行的操作,key接受一个函数。

在下面的例子中,我们需要对字典按价格大小来排序查找。

portfolio = [
    {"name": "IBM", "shares": 100, "price": 91.1},
    {"name": "AAPL", "shares": 50, "price": 543.22},
    {"name": "FB", "shares": 200, "price": 21.09},
    {"name": "HPQ", "shares": 35, "price": 31.75},
    {"name": "YHOO", "shares": 45, "price": 16.35},
    {"name": "ACME", "shares": 75, "price": 115.65}
]
# key接受一个匿名函数,这个函数的作用是找出字典中price的值。
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s["price"])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s["price"])
print(cheap)
print(expensive)
[{"name": "YHOO", "shares": 45, "price": 16.35}, {"name": "FB", "shares": 200, "price": 21.09}, {"name": "HPQ", "shares": 35, "price": 31.75}]
[{"name": "AAPL", "shares": 50, "price": 543.22}, {"name": "ACME", "shares": 75, "price": 115.65}, {"name": "IBM", "shares": 100, "price": 91.1}]

如果你仅仅想查找唯一的最小或最大(N=1)的元素的话,那么使用 min() 和 max() 函数会更快些。

除了使用堆排序,python中还有sorted排序和list.sorted,这两个排序最终生成以列表表示的排序结果,堆排序也是。不过sorted在排序时会新建一个列表再进行排序,而list.sorted会直接对数据进行就地排序,而且要求输入的数据必须为列表。

具名元组

什么是具名元组?有时候我们需要用一个类来表示某个事物,但是并不想定义一个类然后咔哒咔哒写一大段类的表示,这个时候就可以使用具名元组,它可以用来快速生成类。比方说定义一个学生类,属性包括姓名,年龄,学号:

from collections import namedtuple

# 第一个参数是类的名字,第二个参数为类中的数据,可以为字符串,或者字符串组成的列表
Student = namedtuple("Student", ["name", "age", "id"])
Studen = namedtuple("Studen", "name age id")
s1 = Studen("zhuzhezhe", "23", "001")
s2 = Student("zhuzhezhe", "23", "001")
print(s1)
print(s2)
Studen(name="zhuzhezhe", age="23", id="001")
Student(name="zhuzhezhe", age="23", id="001")

具名元组放在collections模块下的nametuple中,第一个参数是类的名字,第二个参数为类中的数据,可以为字符串,或者字符串组成的列表。

以上就是一些不太常见的数据类型的介绍,当然不止这些,具体可以看看python官方手册。

下次我们来说说python中常见数据类型的一些不常见的用法,如果用到了效率会翻倍。


本人才疏学浅,上文中难免有些错误,还请各位品评指正。如果觉得写的还行,欢迎关注我的公众号MLGroup,带你走进机器学习的世界。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44512.html

相关文章

  • Python奇遇数据结构窥探2

    摘要:找出列表中小于的数据除了列表推导式,还有字典推导式,集合推导式,用法都一样。如果你的数据量很大的话,考虑使用生成器表达式。切片不仅对列表有用,同样适用于元组和字符串。切片命名使用方法,内部参数与切片一样。对剩余的的数据,使用星号代替即可。 上次我们讲了几个不常见的数据类型,每个都有自己特殊的用途,虽然不经常用到,了解一下也好。比如我们提到的数组类型,如果在数据量很大的时候同时要效率,就...

    Ocean 评论0 收藏0
  • python奇遇数据结构窥探3

    摘要:字典和集合都是基于散列表实现的,散列表也就是表,了解过数据结构的应该知道。而使用另一种办法,任何键在找不到的情况下都会用中的值数据类型比如替换。在设计时就可以使用创建你的数据接口。 这次主要说说字典和集合这两种数据类型。 字典和集合都是基于散列表实现的,散列表也就是hash表,了解过数据结构的应该知道。与散列表相关的一个概念叫做可散列,什么是可散列?在python官方定义中是这样说的:...

    toddmark 评论0 收藏0
  • Python奇遇:特殊方法窥探

    摘要:在中,特殊方法以双下划线开始,以双下划线结束。真假值,如果向量模为,返回实现向量加法实现向量乘法,例如返回向量的模返回欧几里德范数找个例子运行下。怎么办中有个特殊方法,可以修改控制台输出的样式。 什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init__$,类似于java中的构造器,这个就是特殊方法,也叫作魔术方法。简单来说,特殊方法可以给你设计的...

    niceforbear 评论0 收藏0
  • python奇遇:迭代器和生成器

    摘要:来说说迭代器和生成器,还有可迭代对象和生成器表达式。有点绕是不是,其实,一般只要知道可迭代对象以及它是如何实现的就行了,中常常用生成器来代替迭代器,可以说,生成器就是迭代器。 来说说迭代器和生成器,还有可迭代对象和生成器表达式。 之前简单的提到过,一个对象是可迭代的可以理解为能够使用for循环。这样说其实不太准确,某个对象可迭代是因为它内部实现了$__iter__$这个特殊方法。比如在...

    atinosun 评论0 收藏0
  • python奇遇:隐藏的python功能

    摘要:先不讲数据结构了,这次来说说中一些不被注意的功能。直接交换第二个功能。对的长度使用生成一个序列,然后遍历或者这样第三个功能。其实还接受第二个参数,它的作用是在迭代的过程中如果碰到第二个参数则停止。 先不讲数据结构了,这次来说说python中一些不被注意的功能。 在python的设计哲学中,有这么一条内容:Simple is better than complex,简单的代码比复杂的要好...

    APICloud 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<