5. 数据结构
5.1 列表的更多特性
以下是列表的一些方法.
Test.py:
box = [1, 2, 3]
box.append(4)
print(box)
运行结果:
[1, 2, 3, 4]
***Repl Closed***
此方法可以向列表的末尾添加一个元素.
Test.py:
box = [1, 2, 3]
box.extend(iter(list(range(5))))
print(box)
运行结果:
[1, 2, 3, 0, 1, 2, 3, 4]
***Repl Closed***
extend()
方法可以向列表后追加迭代对象.
Test.py:
box = [1, 2, 3]
box.insert(0, 4)
print(box)
运行结果:
[4, 1, 2, 3]
***Repl Closed***
insert()
可以向指定的位置插入参数, 其位置后的参数向后移.
Test.py:
box = [1, 2, 1, 3]
box.remove(1)
print(box)
运行结果:
[2, 1, 3]
***Repl Closed***
remove()
移除列表中第一个传入参数的值.
Test.py:
box = [1, 2, 1, 3]
box.pop()
print(box)
box.pop(0)
print(box)
运行结果:
[1, 2, 1]
[2, 1]
***Repl Closed***
pop
可以删除指定位置的参数, 默认是删除最后一个参数.
Test.py:
box = [1, 2, 1, 3]
box.clear()
print(box)
运行结果:
[]
***Repl Closed***
clear()
可以删除列表中所有元素.
Test.py:
box = [1, 2, 2, 3]
n = box.index(2)
print(n)
n = box.index(2, 2, 3)
print(n)
运行结果:
1
2
***Repl Closed***
index(x[, start[, end]])
可以返回指定的x所在的索引, 也可以限定搜索范围. 与别的语言不通, 当找不到此参数的时候不是返回 -1
而是会报错.
Test.py:
box = [1, 2, 2, 3]
print(box.count(3))
运行结果:
1
***Repl Closed***
count
函数可以返回传入参数出现的次数.
Test.py:
box = [("n1", 5), ("n2", 2), ("n3", 3), ("n4", 4)]
box.sort()
print(box)
box.sort(key = lambda x:x[1])
print(box)
box.sort(reverse = False)
print(box)
运行结果:
[('n1', 5), ('n2', 2), ('n3', 3), ('n4', 4)]
[('n2', 2), ('n3', 3), ('n4', 4), ('n1', 5)]
[('n1', 5), ('n2', 2), ('n3', 3), ('n4', 4)]
***Repl Closed***
目前 sort
中已经没有 cmp
的参数了. key
主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。reverse
排序规则,reverse = True 降序, reverse = False 升序(默认).
Test.py:
box = [1, 2, 3, 4, 5]
box.reverse()
print(box)
运行结果:
[5, 4, 3, 2, 1]
***Repl Closed***
reverse()
用于反转列表.
Test.py:
box = [1, 2, 3, 4, 5]
box1 = box.copy()
print(box1)
运行结果:
[1, 2, 3, 4, 5]
***Repl Closed***
copy()
返回一个列表的浅复制.
5.1.1 列表作为栈使用
栈作为一个后进后出的结构, 列表完全能够模拟出. 使用append()
进栈 , pop()
出栈.
Test.py:
box = [1, 2, 3, 4, 5]
# 进栈
box.append(6)
print(box)
# 出栈
box.pop()
print(box)
运行结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5]
***Repl Closed***
5.1.2 列表作为队列使用
队列的特性是先进先出, 使用列表本身的方法 insert()
也可以模拟, 但是每次插入和删除都必须将列表中其他元素右移和左移, 所以效率很低, 这里采用 collections.deque
可以快速的进行.
Test.py:
from collections import deque
queue = deque([1, 2, 3, 4])
# 尾部添加元素
queue.append(5)
print(queue)
# 弹出左边的第一个元素
queue.popleft()
print(queue)
# 弹出尾部一个元素
queue.pop()
print(queue)
运行结果:
deque([1, 2, 3, 4, 5])
deque([2, 3, 4, 5])
deque([2, 3, 4])
***Repl Closed***
5.1.3 列表推导式
如何我们要创建一个十个参数的列表, 每个参数是从1-10 各个数字的平方.
Test.py:
box = []
for x in range(10):
box.append(x**2)
print(box)
运行结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
***Repl Closed***
我们也可以使用此的方法来创建.
Test.py:
box = list(map(lambda x:x**2, range(10)))
print(box)
运行结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
***Repl Closed***
map(function, iterable, ...)
第一个参数是一个函数, 第二个以后传的是一个或者多个序列, 用于前面那个函数使用, 函数其返回结果就是map()的返回值.
或者还可以使用以下:
Test.py:
box = [x**2 for x in range(10)]
print(box)
运行结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
***Repl Closed***
使用此方式, 第一个为表达式, 后面跟一个for的子句, 然后是0-n
个for
或者if
子句.
Test.py:
box = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
print(box)
运行结果:
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
***Repl Closed***
5.1.4 嵌套的列表推导式
采用官方中的例子.
Test.py:
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
for i in range(4):
for row in matrix:
print(row[i], end =" ")
print()
matrix = [[row[i] for row in matrix] for i in range(4)]
print(matrix)
运行结果:
1 5 9
2 6 10
3 7 11
4 8 12
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
***Repl Closed***
可能直接看推导式不好理解, 多看翻译过来的语句可以更好的理解.
或者使用:
Test.py:
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
# for i in range(4):
# for row in matrix:
# print(row[i], end =" ")
# print()
# matrix = [[row[i] for row in matrix] for i in range(4)]
# print(matrix)
tt = list(zip(*matrix))
print(tt)
运行结果:
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
***Repl Closed***
zip()
函数的作用官方解释是:用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
大概意思是我们测试提供的列表. 每个子列表算是一个可以迭代的对象, 然后其分别各自取三个中的第一个参数作为一个元组中的参数, 然后一次取2,3,4个元素. 这个方法只是刚好适用于这个要求.
5.2 del 语句
使用 del()
函数可以给定删除指定索引的元素, 其不同与 pop()
的是其不会返回删除的参数, del()
函数同样可以移除切片或是整个列表.
Test.py:
box = [1, 2, 3, 4, 5]
del(box[0])
print(box)
del(box[:])
print(box)
运行结果:
[2, 3, 4, 5]
[]
***Repl Closed***
5.3 元组和序列
元组由几个被逗号隔开的值组成.
Test.py:
box = 1
print(type(box))
box = 1,
print(type(box))
box = (1)
print(type(box))
box = (1,)
print(type(box))
box = (1, 2)
print(type(box))
运行结果:
<class 'int'>
<class 'tuple'>
<class 'int'>
<class 'tuple'>
<class 'tuple'>
***Repl Closed***
可以看到, 元组的构成和方括号还是小括号没有关系, 重点在于要有逗号.
Test.py:
box = 1,2
box[0] = 2
print(box)
运行结果:
Traceback (most recent call last):
File "Test.py", line 2, in <module>
box[0] = 2
TypeError: 'tuple' object does not support item assignment
***Repl Closed***
元组是不支持修改参数的.
Test.py:
box = 1, 2, 3
x, y, z = box
print(x, y, z, sep = "\n")
运行结果:
1
2
3
***Repl Closed***
逆操作, 适用于其他序列
5.4 集合
集合是由不重复元素组成的无序的集, 它主要用于成员检测和消除重复的元素, 集合也支持像联合, 交集, 差集, 对称差分等数学运算.
可以使用 花括号 {}
和 set()
来创建集合, 但是要创建空集合只能使用 set()
而不能用 {}
, 因为这个使用来创建字典的.
Test.py:
box = {}
box1 = {1, 2}
box2 = set()
box3 = set("123")
print(type(box), type(box1), type(box2), type(box3), sep = "\n")
运行结果:
<class 'dict'>
<class 'set'>
<class 'set'>
<class 'set'>
***Repl Closed***
set()
函数只能传递一个对象, 比如传递一个字符串, 则其每个字符都是一个元素, 而不是整个字符串当作一个对象. 所以你要传递多个字符串的集合得传递一个含多个字符串的列表等序列.
交集:
Test.py:
a = {1, 2, 3, 4}
b = {2, 3, 4, 5}
print(a & b)
运行结果:
{2, 3, 4}
***Repl Closed***
并集:
Test.py:
a = {1, 2, 3, 4}
b = {2, 3, 4, 5}
print(a|b)
运行结果:
{1, 2, 3, 4, 5}
***Repl Closed***
差集:
Test.py:
a = {1, 2}
b = {3, 4}
print(a ^ b)
运行结果:
{1, 2, 3, 4}
***Repl Closed***
另外集合也支持列表推导式:
Test.py:
a = {x for x in range(5)}
print(a)
运行结果:
{0, 1, 2, 3, 4}
***Repl Closed***
5.5 字典
字典是以关键字为索引的, 关键字必须是不可变类型, 可以使用字符串, 数字, 或是元组, 但不可是列表. 字典就是一个键值对的集合, 可以通过键的值去获取对应的值, 所以键必须是唯一的,
Test.py:
a = (1,2)
b = 1
c = "1"
box = {a : "1", b : "2", c : "3"}
print(box)
运行结果:
{(1, 2): '1', 1: '2', '1': '3'}
***Repl Closed***
可以使用list(dict)
来获取字典的 key
, 查找是否存在 key
即可用 in
.
Test.py:
box = {1 : "1!", 2 : "2!"}
print(list(box))
运行结果:
[1, 2]
***Repl Closed***
Test.py:
box = {1 : "1!", 2 : "2!"}
print(1 in box)
运行结果:
True
***Repl Closed***