Python基础-5 常用的数据结构

2022-12-06 09:03:35 浏览数 (1)

数据结构

简单介绍Python中常用的几种数据结构。

1. 列表 list

列表类似于其它编程语言里的可变数组。

标准库参考:“列表是可变序列,通常用于存放同类项目。”

1.1 列表的创建

  • • 使用方括号创建空列表:[]
  • • 使用方括号,里面的项用,隔开:[a,b,c]
  • • 使用列表推导式:[x for x in iterable]
  • • 使用构造器: list()或list(iterable)

构造器会返回一个列表,其中的项与iterable中的项值和顺序都相同。iterable是一个可迭代对象。

1.2 列表的操作

列表是可变序列,因此它支持通用序列操作可变序列操作

通用序列操作:支持判断,求值等操作,但不可修改序列内容。

可变序列操作:除了通用序列操作,还支持对序列元素赋值、删除等修改操作。

列表额外方法

sort(*, key=None, reverse=False)

就地排序列表中的元素。key是有一个参数的函数,用来生成用于比较的键;reverse是True或False,表示是否反转。*用来限定后面的参数仅能通过关键字方式传递。

代码语言:javascript复制
lst1 = [1,2,3,7,3,4]
lst1.sort()
print(lst1)

key参数很适合用lambda表达式:

代码语言:javascript复制
scores = [('a', 99), ('b', 66), ('c', 77), ('d', 88)]
scores.sort(key=lambda x: -x[1])
print(scores)

使用列表实现堆栈、队列

堆栈是一种后进先出的数据结构。可以将堆栈想象成一口井。

(堆栈:进的顺序是1,2,3,4。出的顺序是4,3,2,1。)

使用列表实现堆栈非常容易,用append()模拟进栈,pop()模拟出栈。

代码语言:javascript复制
stack = [1, 2, 3]
stack.append(4)
stack.append(5)
print(stack)

stack.pop()
print(stack)

stack.pop()
stack.pop()

print(stack)

队列是一种先进先出的数据结构。相当于排队。

(队列:进的顺序1,2,3,4.出的顺序也是1,2,3,4)

可以使用append()模拟入队,pop(0)模拟出队,但是时间效率低。

一般用collections.deque实现。append()模拟入队,popleft()模拟出队。

代码语言:javascript复制
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")           # Terry arrives
queue.append("Graham")          # Graham arrives
queue.popleft()                 # The first to arrive now leaves

queue.popleft()                 # The second to arrive now leaves

queue                           # Remaining queue in order of arrival

2. 元组

元组是不可变序列,通常用于存储多项集。或用于需要数据不可变的情况(如存储到set中)。

2.1 元组的创建

可以用多种方式构建元组:

  • • 使用一对圆括号来表示空元组: ()
  • • 使用一个后缀的逗号来表示单元组: a,(a,)
  • • 使用以逗号分隔的多个项: a, b, c or (a, b, c)
  • • 使用内置的 tuple(): tuple()tuple(iterable)

请注意决定生成元组的其实是逗号而不是圆括号。圆括号只是可选的,生成空元组或需要避免语法歧义的情况除外。例如,f(a, b, c) 是在调用函数时附带三个参数,而 f((a, b, c)) 则是在调用函数时附带一个三元组。

2.2 元组的操作

元组是不可变序列,实现了所有通用序列的操作。

2.3 扩展内容:命名元组

通过名称访问相比通过索引访问清晰collections.namedtuple() 提供了命名元组的方法。

代码语言:javascript复制
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

返回一个新的元组子类,名为 typename 。这个新的子类用于创建类元组的对象,可以通过字段名来获取属性值,同样也可以通过索引和迭代获取值。

子类实例同样有文档字符串(类名和字段名)。另外一个有用的 __repr__() 方法,以 name=value 格式列明了元组内容。

field_names 是一个像 [‘x’, ‘y’] 一样的字符串序列。 field_names 也可以是一个纯字符串,用空白或逗号分隔开元素名,比如 'x y' 或者 'x, y'

代码语言:javascript复制
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y']) #namedtuple('Point', 'x, y')
p = Point(1, 2)
print(p[0]   p[1])
print(p.x   p.y)

命名元组尤其有用于赋值 csv sqlite3 模块返回的元组

代码语言:javascript复制
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print(emp.name, emp.title)

除了继承元组的方法,命名元组还支持三个额外的方法和两个属性。为了防止字段名冲突,方法和属性以下划线开始。

三个方法

classmethod somenamedtuple._make(iterable)

类方法从存在的序列或迭代实例创建一个新实例。

代码语言:javascript复制
t = [11, 22]
Point._make(t)

somenamedtuple._asdict()

返回一个新的 dict ,它将字段名称映射到它们对应的值:

代码语言:javascript复制
p = Point(x=11, y=22)
p._asdict()
#{'x': 11, 'y': 22}

somenamedtuple._replace(**kwargs)

返回一个新的命名元组实例,并将指定域替换为新的值

代码语言:javascript复制
p = Point(x=11, y=22)
p._replace(x=33)

两个属性

somenamedtuple._fields

字符串元组列出了字段名。用于提醒和从现有元组创建一个新的命名元组类型。

代码语言:javascript复制
p._fields            # view the field names


Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields   Color._fields)
Pixel(11, 22, 128, 255, 0)

somenamedtuple._field_defaults

字典将字段名称映射到默认值。

代码语言:javascript复制
Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
Account._field_defaults
# {'balance': 0}
Account('premium')
# Account(type='premium', balance=0)

要获取这个名字域的值,还可以使用 getattr() 函数 :

代码语言:javascript复制
getattr(p, 'x')

转换一个字典到命名元组,使用 ** 两星操作符

代码语言:javascript复制
d = {'x': 11, 'y': 22}
Point(**d)

命名元组是一个正常的Python类,它可以很容易通过子类更改功能。

代码语言:javascript复制
class Point(namedtuple('Point', ['x', 'y'])):
    __slots__ = ()
    @property
    def hypot(self):
        return (self.x ** 2   self.y ** 2) ** 0.5
    def __str__(self):
        return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

for p in Point(3, 4), Point(14, 5/7):
    print(p)

通过直接赋值给 __doc__ 属性,更改文档字符串

代码语言:javascript复制
Book = namedtuple('Book', ['id', 'title', 'authors'])
Book.__doc__  = ': Hardcover book in active collection'
Book.id.__doc__ = '13-digit ISBN'
Book.title.__doc__ = 'Title of first printing'
Book.authors.__doc__ = 'List of authors sorted by last name'

0 人点赞