数据结构
list(列表)
# list.append(x)
squares = [1, 2, 3, 4 ,5, 6]
squares.append(10)
print(squares) # [1, 2, 3, 4, 5, 6, 10]
# list.extend(iterable)
iterable = [x * 2 for x in squares]
squares.extend(iterable)
print(squares) # [1, 2, 3, 4, 5, 6, 10, 2, 4, 6, 8, 10, 12, 20]
# list.insert(i, x)
square2 = [1, 2, 3, 4]
square2.insert(2, 11)
print(square2) # [1, 2, 11, 3, 4]
# list.remove(x)
square3 = [1, 2, 3, 4]
square3.remove(2)
print(square3) # [1, 3, 4]
# list.pop([i])
square4 = [1, 2, 3, 4]
square4.pop(2)
print(square4) # [1, 2, 4]
square4.pop()
print(square4) # [1, 2]
# list.clear()
square5 = [1, 2, 3, 4]
square5.clear()
print(square5) # []
# list.count
square5 = [1, 2, 3, 4]
square5.clear()
print(square5) # []
# list.sort(key=None, reverse=false)
square6 = [1, 2, 3, 3, 4]
print(square6.count(3)) # 2
# list.clear()
square5 = [1, 2, 3, 4]
square5.clear()
print(square5) # []
# list.copy() => 返回浅拷贝
square6 = [1, 2, 3, 4]
square7 = square6.copy()
print(square7) # [1, 2, 3, 4]
square7.remove(2)
print(square7) # [1, 3, 4]
print(square6) # [1, 2, 3, 4]
# list.reverse()
square8 = [1, 2, 3, 4]
square8.reverse()
print(square8) # [4, 3, 2, 1]
# list.index(x[, start[, end])
square9 = [1, 2, 3, 4]
print(square9.index(2)) # 2的索引值为1
print(square9.index(2, 0, 9)) # 1
你可能会注意到的另一件事是,并非所有数据都可以排序或比较。例如,[None,‘hello’,10]之所以不能排序,是因为不能将整数与字符串进行比较,而不能将None与其他类型进行比较。另外,有些类型没有定义排序关系。例如,3 + 4j < 5 + 7j不是有效的比较。
也可以将列表用作队列,其中添加的第一个元素是检索到的第一个元素(“先进先出”);但是,列表对于此目的并不有效。尽管从列表末尾开始的添加和弹出很快速,但是从列表开头进行插入或弹出是很慢的(因为所有其他元素都必须移位一个)。
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry") # deque(['Eric', 'John', 'Michael', 'Terry'])
print(queue)
queue.append("Graham") # deque(['Eric', 'John', 'Michael', 'Terry', 'Graham'])
print(queue)
queue.popleft() # deque(['John', 'Michael', 'Terry', 'Graham'])
print(queue)
queue.popleft() # deque(['Michael', 'Terry', 'Graham'])
print(queue)
列表推导
列表推导可以很精简的创建一个列表
# 传统方法
ary = []
for var in range(10):
ary.append(var)
print(ary) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 列表推导方式
ary2 = [x for x in range(0, 10)]
print(ary2) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ary3 = [1, 2, 3, 4, 5]
new_ary3 = list(map(lambda x: x ** 2, ary3))
print(new_ary3) # [1, 4, 9, 16, 25]
# 等价于上面一种写法
ary4 = ary3.copy()
new_ar4 = [x**2 for x in ary4]
print(new_ar4) # [1, 4, 9, 16, 25]
列表推导由包含表达式的方括号组成,后跟一个for子句,然后是零个或多个for或if子句。结果将是一个新列表,该列表是通过在紧随其后的for和if子句的上下文中计算表达式而得出的:
ary1 = [1, 2, 3, 4, 5, 6]
ary2 = [1, 2, 3, 4, 5, 6]
combine_ary = [(x, y) for x in ary1 for y in ary2 if x != y]
print(combine_ary)
# 等价于上面
arr = []
for x in ary1:
for y in ary2:
if x == y: continue
arr.append((x, y))
print(arr)
vec = [-4, -2, 0, 2, 4]
print([x * 2 for x in vec]) # [-8, -4, 0, 4, 8]
print([x for x in vec if x > 0]) # [2, 4]
print([abs(x) for x in vec]) # [4, 2, 0, 2, 4]
# 调用方法处理元素,返回一个新的数组
freshfruit = [' banana', ' loganberry ', 'passion fruit ']
print([x.strip() for x in freshfruit]) # ['banana', 'loganberry', 'passion fruit']
# print([x, x**2 for x in range(6)]) # error
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print([num for elem in vec for num in elem])
# 等价于上面
new_ary2 = []
for x in vec:
for y in x:
new_ary2.append(y)
print(new_ary2)
from math import pi
print([str(round(pi, i)) for i in range(1, 6)])
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
print([[ary[i] for ary in matrix] for i in range(0, len(matrix))]) # [[1, 5, 9], [2, 6, 10], [3, 7, 11]]
# same as above
new_ary3 = []
for i in range(len(matrix)):
new_ary3.append([ary[i] for ary in matrix])
print(new_ary3) # [[1, 5, 9], [2, 6, 10], [3, 7, 11]]
# same as above
new_ary4 = []
for i in range(len(matrix)):
temp_ar = []
for ary in matrix:
temp_ar.append(ary[i])
new_ary4.append(temp_ar)
print(new_ary4) # [[1, 5, 9], [2, 6, 10], [3, 7, 11]]
print(list(zip(*matrix))) # [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
delete 语句
a = [-1, 1, 66.25, 333, 333, 1234.5]
del a[0]
print(a) # [1, 66.25, 333, 333, 1234.5]
del a[2:4]
print(a) # [1, 66.25, 1234.5]
del a[:] # same as a.clear()
print(a) # []
元组和序列
元组由逗号分隔开的元素组成,元组是不可变得。
t = 12345, 54321, 'hello!'
print(t[0]) # 12345
# Tuples may be nested:
u = t, (1, 2, 3, 4, 5)
print(u) # ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
# Tuples are immutable:
t[0] = 88888 # error
# but they can contain mutable objects:
v = ([1, 2, 3], [3, 2, 1])
print(v) # ([1, 2, 3], [3, 2, 1])
empty = ()
singleton = 'hello', # <-- note trailing comma
print(len(empty)) # 0
print(len(singleton)) # 1
print(singleton) # ('hello', )
x, y, z = t # unpack tuple
这被适当地称为序列解压缩,适用于右侧的任何序列。序列解压缩要求等号左侧的变量与序列中的元素一样多。注意,多重分配实际上只是元组打包和序列拆包的组合。
集合
Python还包括集合的数据类型。集合是没有重复元素的无序集合。基本用途包括成员资格测试和消除重复条目。集合对象还支持数学运算,例如并集,交集,差和对称差。
花括号或set()函数可用于创建集合。注意:要创建一个空集,必须使用set(),而不要使用{};后者会创建一个空字典。
aa = {1, 2, 3}
bb = {1, 2, 3, 4, 5, 6}
print(aa - bb)
print(aa | bb) # {1, 2, 3, 4, 5, 6}
print(aa & bb) # {1, 2, 3}
print(aa ^ bb) # {4, 5, 6}
print(set('abcdefg')) # {'b', 'd', 'g', 'a', 'e', 'f', 'c'}
print({'apple', 'apple', 'orange'}) # {'apple', 'orange'}
集合也支持列表推导
a = {x for x in 'abracadabra' if x not in 'abc'}
print(a) # {'r', 'd'}
print(set('abc') ^ set('abracadabra')) # same as {'r', 'd'}
字典
tel = {'jack': 4098, 'sape': 4139}
tel['guido'] = 4127
print(tel) # {'jack': 4098, 'sape': 4139, 'guido': 4127}
print(tel['jack']) # 4098
del tel['sape']
tel['irv'] = 4127
print(tel) # {'jack': 4098, 'guido': 4127, 'irv': 4127}
print(list(tel)) # ['jack', 'guido', 'irv']
print(sorted(tel)) # ['guido', 'irv', 'jack']
print('guido' in tel) # True
print('jack' not in tel) # False
dict()构造函数直接从键值对序列中构建字典:
print(dict([[1, 2], [2, 3]])) # {1: 2, 2: 3}
print(dict([(1, 2), (2, 3)])) # {1: 2, 2: 3}
print({x: x**2 for x in (2, 4, 6)}) # {2: 4, 4: 16, 6: 36}
#如果键是字符串,则可以用关键字参数形式来创建一个字典
print(dict(sape=4139, guido=4127, jack=4098)) # {'sape': 4139, 'guido': 4127, 'jack': 4098}
循环
当遍历字典时,可以使用items()方法同时检索键和对应的值。
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
print(k, v)
遍历序列时,可以使用enumerate()函数同时检索位置索引和相应的值。
for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)
要同时循环两个或多个序列,可以将这些条目与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))
要反向循环一个序列,请先在正向指定序列,然后调用reversed()函数。
for i in reversed(range(1, 10, 2)):
print(i)
要按排序顺序循环显示序列,请使用sorted()函数,该函数返回一个新的排序列表,同时保持源不变。
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for f in sorted(set(basket)):
print(f)
当遍历列表时,有时很想更改列表。但是,创建新列表通常更简单,更安全。
import math
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比较运算符检查序列中是否出现值(不发生)。运算符比较两个对象是否确实是同一对象;是否比较?这仅适用于可变对象(如列表)。所有比较运算符都具有相同的优先级,该优先级低于所有数值运算符的优先级。
比较可以是链式的。例如, a < b == c 测试a是否小于b并且b等于c.
布尔运算符和和或所谓的短路运算符:它们的自变量从左到右进行求值,并且在确定结果后立即停止求值。例如,如果A和C为true但B为false,则A和B与C不会对表达式C求值。当用作通用值而不是布尔值时,短路运算符的返回值是最后一个表达式计算值。
string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
non_null = string1 or string2 or string3
print(non_null) # 'Trondheim'
var = 0 or 2
print(var) # 2
var2 = 1 and 3
print(var2) # 3
比较序列和其他类型
通常可以将序列对象与具有相同序列类型的其他对象进行比较
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