数据结构
深入列表
函数
列表数据类型有很多的方法,如下表
| 在末尾添加一项内容. 相当于a[len(a):] = [x] . | |
| 通过遍历器中的所有项扩展列表. 相当于 a[len(a):] = iterable . | |
| 在给定位置插入一项。i位插入位置的索引所以a.insert(0, x) 将插入在最前面,并且a.insert(len(a), x) 等价于a.append(x) | |
| 删除列表中值为x的项目 | |
| 删除指定位置的项目并返回它。如果没有指定索引a.pop() 则删除最后一项。([]代表i为可选参数,而不是要输入它) | |
| 删除列表所有项。相当于del a[:] | |
| 返回第一个值为x的项目索引。start和end表示只查找这个区间内的项目。 | |
| 返回列表中值x出现的次数 | |
| 列表排序。key排序关键字,reverse是否为倒序 | |
| 将列表中的元素反向放置。 | |
| 返回列表的浅拷贝。相当于a[:] |
列表堆栈
我们可以将列表当做堆栈使用,例如
stack = [3, 4, 5]
stack.append(6)
stack.append(7)
print(stack)
print(stack.pop())
print(stack.pop())
print(stack.pop())
print(stack.pop())
# 结果:
# [3, 4, 5, 6, 7]
# 7
# 6
# 5
# 4
列表队列
我们可以将列表当做队列使用,例如
普通列表从末尾增减项目的速度都很快,但是从首位增减项目时所有项目都要向前移动一位,效率较低。
所以我们使用collections.deque
来实现队列,它两端都能快速地增减数据。
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")
queue.append("Graham")
print(queue)
print(queue.popleft())
print(queue.popleft())
列表解析
列表解析是通过一个循环表达式来生成列表的方式。
循环表达式主要由两部分组成 前半部分为算式,后半部分为循环控制。例如
squares = [x**2 for x in range(10)]
相当于
squares = []
for x in range(10):
squares.append(x ** 2)
print(squares)
复杂情况下可能存在多个循环和判断
squares = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]
相当于
squares = []
for x in [1, 2, 3]:
for y in [3, 1, 4]:
if x != y:
squares.append((x, y))
嵌套列表解析
列表解析可以是任意表达式,其中包括另一个列表解析表达式
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transposed = [[row[i] for row in matrix] for i in range(4)]
相当于
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transposed = []
for i in range(4):
transposed.append([row[i] for row in matrix])
也相当于
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transposed = []
for i in range(4):
transposed_row = []
for row in matrix:
transposed_row.append(row[i])
transposed.append(transposed_row)
本例也可以使用内置函数更方便的得到结果
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transposed = list(zip(*matrix))
删除语句
我们可以使用del来删除列表中的数据
array = [-1, 1, 66.25, 333, 333, 1234.5]
del array[0]
print(array) # 结果[1, 66.25, 333, 333, 1234.5]
del array[2:4]
print(array) # 结果[1, 66.25, 1234.5]
del array[:]
print(array) # 结果[]
del array
# print(array) # 结果报错 UnboundLocalError: local variable 'a' referenced before assignment
元组和序列
元组是由若干个以逗号分隔的值组成
tuple1 = 12345, 54321, 'hello!'
print(tuple1[0]) # 结果 12345
print(tuple1) # 结果 (12345, 54321, 'hello!')
# 元祖是可以嵌套的
unit = tuple1, (1, 2, 3, 4, 5)
print(unit) # 结果 ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
# 元组是不可变的
# tuple1[0] = 88888 # 报错 TypeError: 'tuple' object does not support item assignment
# 元组可以包含可变对象
tuple2 = [1, 2, 3], [3, 2, 1]
tuple2[0][0] = 3
print(tuple2) # 结果 ([3, 2, 3], [3, 2, 1])
空元组用一对括号表示
empty = ()
print(empty) # 结果 ()
我们可以使用序列解压缩将元祖赋值给多个变量(变量数量要求与元组内容数量一样)
compress = 12345, 54321, 'hello!'
first, second, third = compress
print(first)
print(second)
print(third)
# 结果 12345
# 54321
# hello!
集合
类似于java是一个无需不重复集合。
创建集合时必须要使用set()函数,而不是{}。{}是用于创建一个空的字典。
# 重复项将被删除
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket) # 结果 {'apple', 'orange', 'pear', 'banana'}
# 判断是否在集合中
print('orange' in basket) # 结果 True
print('crabgrass' in basket) # 结果 False
# 字母集合的运算
set1 = set('abracadabra')
set2 = set('alacazam')
print(set1) # 结果 {'a', 'd', 'b', 'r', 'c'}
print(set2) # 结果 {'z', 'a', 'l', 'm', 'c'}
print(set1 - set2) # 结果 {'d', 'b', 'r'}
print(set1 | set2) # 结果 {'z', 'a', 'l', 'm', 'd', 'b', 'r', 'c'}
print(set1 & set2) # 结果 {'a', 'c'}
print(set1 ^ set2) # 结果 {'z', 'r', 'd', 'b', 'l', 'm'}
集合也支持表达式解析
# 解析表达式
set3 = {x ** 2 for x in range(10)}
print(set3) # 结果 {'z', 'r', 'd', 'b', 'l', 'm'}
字典
字典是一组键值对组合,统一字典中键是唯一的。创建一个新的空字典使用{}
# 创建空字典
tel = {}
print(tel) # 结果{}
# 添加元素
tel['second'] = 2
tel['first'] = 1
print(tel) # 结果{'second': 2, 'first': 1}
# 修改元素值
tel['first'] = 100
print(tel) # 结果{'second': 2, 'first': 100}
# 获取元素值
print(tel['second']) # 结果 2
# 获取字典所有的键
print(list(tel)) # 结果 ['second', 'first']
# 对字典键排序
print(sorted(tel)) # 结果 ['first', 'second']
# 检查元素是否存在
print('first' in tel) # 结果 True
# 检察元素是否不存在
print('first' not in tel) # 结果 False
# 删除元素
del tel['second']
print(tel) # 结果 {'first': 100}
dict()函数可以直接从键值对序列创建字典
print(dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]))
# 结果 {'sape': 4139, 'guido': 4127, 'jack': 4098}
也可以通过表达式解析创建字典
print({x: x ** 2 for x in (2, 4, 6)})
# 结果{2: 4, 4: 16, 6: 36}
循环的技巧
在检索字典时可以使用items()函数,同时检索键和值。
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
print(k + ":" + v)
# 结果 gallahad:the pure
# robin:the brave
遍历序列时可以使用enumerate()函数,同时检索位置和值。
for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)
# 结果 0 tic
# 1 tac
# 2 toe
同时循环两个以上的序列,可以使用zip()函数进行配对
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
print('What is your {0}? It is {1}.'.format(q, a))
# 结果 What is your name? It is lancelot.
# What is your quest? It is the holy grail.
# What is your favorite color? It is blue.
使用reversed()函数可以反向循环序列
questions = ['name', 'quest', 'favorite color']
for q in questions:
print(q)
for q in reversed(questions):
print(q)
# 结果 name
# quest
# favorite color
# favorite color
# quest
# name
使用sorted()函数可以排序循环序列。此函数返回一个新的排序序列,对原来的序列没有影响。
questions = ['name', 'quest', 'favorite color']
for q in sorted(questions):
print(q)
for q in questions:
print(q)
# 结果 favorite color
# name
# quest
# name
# quest
# favorite color
有时可能会想在循环时修改列表内容,一般来说改为创建一个新列表是比较简单且安全的
raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
filtered_data = []
for value in raw_data:
if not math.isnan(value):
filtered_data.append(value)
print(filtered_data)
# 结果 [56.2, 51.7, 55.3, 52.5, 47.8]
深入条件控制
while 和 if 条件句中可以使用任意操作,而不仅仅是比较操作。
in | 校验一个值是否在一个序列里。 | |
not in | 校验一个值是否不在一个序列里。 | |
is | 比较两个对象是同一个对象。 | |
is not | 比较两个对象不是同一个对象。 | |
and | 与操作 | |
or | 或操作 | |
not | 非操作 | |
序列和其它类型的比较
序列可以与其他类型的序列进行比较。
比较规则为先比较第一项,如果相同则继续向后比较,直至有一个序列耗尽。
print((1, 2, 3) < (1, 2, 4)) # 结果 True
print([1, 2, 3] < [1, 2, 4]) # 结果 True
print('ABC' < 'C' < 'Pascal' < 'Python') # 结果 True
print((1, 2, 3, 4) < (1, 2, 4)) # 结果 True
print((1, 2) < (1, 2, -1)) # 结果 True
print((1, 2, 3) == (1.0, 2.0, 3.0)) # 结果 True
print((1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)) # 结果 True