疫情严重 在家工作 学习python数据结构与算法分析一书
日更 希望能坚持下去
第一章 python基础
1.python语句中 变量存的是指向数据的引用
A = [1, 2, 3, 4]
B = A
A.append(5)
print(B)
[1, 2, 3, 4, 5]
上例所示 ’B = A‘ 语句中,B存储的是A的地址 所以当A发生变化时,B也会随之变化
再举一例:
a = 1
b = 1
c = 1
print(id(a), id(b), id(c))
>>> 1871344272 1871344272 1871344272
a = [1, 2, 3]
b = [1, 2, 3]
c = [1, 2, 3]
a1 = a
a2 = a1
print(id(a), id(b), id(c), id(a1), id(a2))
>>> 2539520041992 2539520042888 2539468066312 2539520041992 2539520041992
可变数据类型:列表list和字典dict
不可变数据类型:整型int、浮点型float、字符串型string和元组tuple
当使用不可变数据类型时,赋值相同的变量会指向同一地址
当使用不可变数据类型时,赋值相同的变量会指向不同的地址
概括描述为:
python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。
(概述引自CSDN,链接 https://blog.csdn.net/shen_chengfeng/article/details/80687396)
2.内建集合数据类型
有序集合:列表、字符串、元组
无序集合:集(set)、字典
一系列可应用于任意pyhton序列的运算:
索引 [] 取序列中的某个元素
连接 + 将序列连接在一起
重复 * 重复N次连接
成员 in 查询是否有某元素
长度 len 查询序列元素的个数
切片 [:] 取出序列的一部分
>>> mylist = [1,2,3]
>>> A = [mylist]*3
>>> A
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
>>> myname = "LOG"
>>> myname
'LOG'
>>> myname[1:2]
'O'
>>>
列表 [ ]
列表是异构的,其指向的数据对象不需要都是同一个类
>>> mylist = [1,3,True,'avc', 1.13]
>>> mylist
[1, 3, True, 'avc', 1.13]
>>>
>>> mylist = [1,2,3]
>>> A = [mylist]*3
>>> A
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
列表中常用方法汇总:append(末尾添加) insert(插入) pop(删除并返回) sort(顺排序) reverse(倒排序) del(删除)
index(返回item第一次出现时的下标) count(返回item在列表中出现的次数)
remove(从列表中移除第一次出现的item)
mylist.append(5) 可读作“请求mylist调用其append方法并将5这一值传给它”
>>> mylist
[1, 3, True, 'avc', 1.13]
>>> mylist.pop()
1.13
>>> mylist
[1, 3, True, 'avc']
>>> len(mylist)
4
字符串 ' '
字符串中常用方法汇总:
center(w)、ljust(w)、rjust(w)(返回一个长度为w的字符串,且原字符串居中/左/右)
conut(item)、find(item) (返回item出现的次数/第一次出现的位置)
lower()、upper()(返回均为小/大写的字符串)
split(schar) 在schar位置将字符串分割成子串 (数据处理非常实用)
>>> myname = 'David'
>>> myname.split('v')
['Da', 'id']
>>> myname.split('d')
['Davi', '']
>>> myname.split('D')
['', 'avid]
列表和字符串的主要区别在于,列表能够被修改,字符串则不能。
元组 ( )
元组与列表都是异构的数据序列,区别在于元组也不能修改。
元组中常用的方法同序列一样,不再赘述
集 { }
集是由0个或多个不可修改的python数据对象组成的异构无序集合,集不允许出现重复元素
>>> myset = {3,6,'cat',4.5, False}
>>> myset
{False, 3, 4.5, 'cat', 6}
>>> len(myset)
5
>>> 3 in myset
True
>>> 83 in myset
False
>>>
由于集应用较少,不做展开,具体应用方法见书P13
字典 key:value
字典是无序结构,由键—值对构成,如下:
>>> dic = {'a':1, 'b':2}
>>> dic
{'b': 2, 'a': 1}
访问字典的语法与访问序列的语法相似,序列使用下标,字典使用键值
>>> dic['b']
2
>>> dic['c']=3
>>> dic
{'b': 2, 'a': 1, 'c': 3}
>>> len(dic)
3
注:字典本身是无序的,键的位置是由散列决定的
字典支持的运算
[] adict[k] 返回与k相关联的值,如果没有则报错
in key in adict 如果key在字典中 返回True 否则False
del del adict[key] 从字典中删除key键—值对
字典提供的方法
keys() / values() / items() 返回包含字典中所有键/值/键—值对的对象
>>> dic
{'b': 2, 'a': 1, 'c': 3}
>>> list(dic.keys())
['b', 'a', 'c']
>>> list(dic.items())
[('b', 2), ('a', 1), ('c', 3)]
get(k) 返回k对应的值,如果没有则返回None
get(k, ooooh!!!) 返回k对应的值,如果没有则返回ooooh!!!
>>> dic.get('d','ooooh!')
'ooooh!'
>>> dic.get('c','oooooh!')
3
3 控制结构
算法中两个重要的控制结构: 迭代和分支
迭代while 和 for,分支使用if
while语句会在给定条件为真时重复执行一段代码
cont = 1
while cont <=6:
print('hello', 'world', sep='***')
cont = cont+1
print('over')
hello***world
hello***world
hello***world
hello***world
hello***world
hello***world
over
for则可以用于遍历一个序列集合中的每个成员,同理可用于处理字符串中的每一个字符
for i in range(0, 10, 2):
print(i)
print('over')
0
2
4
6
8
over
word_list = ['cat', 'dog', 'rabbit']
letter_list = []
for word in word_list:
for letter in word:
letter_list.append(letter)
print(letter_list)
['c', 'a', 't', 'd', 'o', 'g', 'r', 'a', 'b', 'b', 'i', 't']
使用迭代结构和分支结构可以创建列表解析式,例如创建一个只包含1到20中奇数的平方数的列表:
list_20 = [i*i for i in range(1, 20, 1) if i%2 !=0]
print(list_20)
[1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
letter_list = [ch.upper() for ch in 'attention is all you need' if ch not in 'aeiou']
print(letter_list)
['T', 'T', 'N', 'T', 'N', ' ', 'S', ' ', 'L', 'L', ' ', 'Y', ' ', 'N', 'D']
4 函数
举例:通过牛顿迭代法求解平方根
def squareroot(n):
root = 2 / n
for k in range(21):
root = 1 / 2 * (root + n / root)
return root
a = squareroot(4563)
print(a)
5 定义类
举例:分数的加减、约分、相等判别
def GCD(m, n):
while m % n != 0:
old_m = m
old_n = n
m = old_n
n = old_m % old_n
return n
class Fraction(object):
def __init__(self, top, bottom):
self.num = top
self.den = bottom
def show(self):
print(self.num, self.den, sep='/')
def __str__(self):
return str(self.num) + '/' + str(self.den)
def __add__(self, other_fraction):
new_num = self.num * other_fraction.den + self.den * other_fraction.num
new_den = self.den * other_fraction.den
common_num = GCD(new_num, new_den)
result_add = Fraction(new_num//common_num, new_den//common_num)
if result_add.den is 1:
return result_add.num
return result_add
def __eq__(self, other):
first_num = self.num * other.den
second_num = self.den * other.num
return first_num == second_num
f1 = Fraction(3, 5)
f2 = Fraction(2, 5)
result_eq = f1.__eq__(f2)
print(result_eq)
result_add = f1.__add__(f2)
print(result_add)