1random模塊的使用
- random.random()函數(shù)是這個(gè)模塊中最常用的方法了,它會(huì)生成一個(gè)隨機(jī)的浮點(diǎn)數(shù),范圍是在0.0~1.0之間
- random.uniform(a,b)正好彌補(bǔ)了上面函數(shù)的不足,它可以設(shè)定浮點(diǎn)數(shù)的范圍,一個(gè)是上限,一個(gè)是下限。
- random.randint(a,b)隨機(jī)生一個(gè)整數(shù)int類型,可以指定這個(gè)整數(shù)的范圍,同樣有上限和下限值
- random.choice(seq)可以從任何序列,比如list列表中,選取一個(gè)隨機(jī)的元素返回,可以用于字符串、列表、元組等
- random.shuffle(seq)如果你想將一個(gè)序列中的元素,隨機(jī)打亂的話可以用這個(gè)函數(shù)方法,會(huì)作原地修改。
- random.sample(seq,num)可以從指定的序列中,隨機(jī)的截取指定長度的片斷,不作原地修改。
2string模塊的使用
- ascii_letters生成所有英文字母(包括大小寫)
- digits生成所有數(shù)字
- ascii_letters+string.digits生成所有英文字母及數(shù)字(a-zA-Z0-9)
random.sample(string.ascii_letters+string.digits,5)從所有字母及數(shù)字中隨機(jī)選出5個(gè)字符
3冒泡排序
def sear(list1):
for i in range(len(list1)):
for j in range(1, len(list1) - i):
if list1[j - 1] > list1[j]:
list1[j - 1], list1[j] = list1[j], list1[j - 1]
4二分查找法
需要先對(duì)其排序才能使用二分查找法
def spl(list1, num):
sear(list1)# 調(diào)用二分查找法對(duì)其進(jìn)行排序
start = 0
end = len(list1)
while start != end:
middle = start + end >> 1
if num > list1[middle]:
start = middle
elif num < list1[middle]:
end = middle
else:
return middle
5選擇排序
def xuanze(list1):
for i in range(len(list1)):
k = i
for j in range(k + 1, len(list1)):
if list1[k] > list1[j]:
k = j
if k != i:
list1[i], list1[k] = list1[k], list1[i]
快速排序
def quik_sort(data):
"""快速排序"""
if len(data) <= 1:
return data
middle = data.pop(0)
first = []
curr = [middle]
third = []
for val in data:
if val < middle:
first.append(val)
elif val > middle:
third.append(val)
elif val == middle:
curr.append(val)
return quik_sort(first) + curr + quik_sort(third)
6菲波拉切序列
def feibo(num1, num2, num3):
start, second = num1, num2
if num3 < 3:
list1 = [num1, num2]
print(num1, num2)
else:
list1 = [num1, num2]
for _ in range(num3 - 2):
current = start + second
start = second
second = current
list1.append(current)
7求素?cái)?shù)
from math import sqrt
def sushu(list1):
list2 = []
for num in list1:
num1 = int(sqrt(num))
for j in range(2, num1+1):
if num%j == 0:
break
else:
list2.append(num)
return list2
8跑馬燈效果
def main():
content='歡迎來到成都'
while True:
os.system('cls')
#清屏
print(content)
time.sleep(0.5)
#每隔0.5秒刷新一次
content=content[1:]+content[0]
9短除法求最大公約數(shù)
def gcd(x,y):
if x>y:
return gcd(y,x)
elif y%x ==0:
return x
else:
return gcd(y%x,x)
10隨機(jī)走臺(tái)階
def walk(n):
#10級(jí)臺(tái)階,隨機(jī)走一級(jí),二級(jí),三級(jí),有多少種走法
if n<0:
return 0
elif n==0:
return 1
return walk(n-1)+walk(n-2)+walk(n-3)
11漢落塔
def hanoi(n,a,b,c):
#漢洛塔
if n>0:
hanoi(n-1,a,c,b)
print(a,'→',b)
hanoi(n-1,c,b,a)
hanoi(4,A,B,C)
12單例
12.1使用new方法
# 創(chuàng)建單例類(法一:使用__new__方法)
class Singleton:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
# 繼承單例類
class MyClass(Singleton):
a = 1
12.2共享屬性
# 創(chuàng)建單例類(法二:共享屬性)
class Brog:
_state = {}
def __new__(cls, *args, **kwargs):
ob = super(Brog, cls).__new__(cls, *args, **kwargs)
ob.__dict__ = cls._state
return ob
class MyClass2(Brog):
a = 1
12.3使用裝飾器
# 創(chuàng)建單例類(法三:裝飾器版本)
def singleton(cls, *args, **kwargs):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return getinstance
@singleton
class MyClass3:
a = 2
13回文字符判斷
def huiwen(s):
start = len(s)
mid = start//2
for i in range(mid+1):
if s[i] != s[start-1-i]:
print('%s不是回文字符'%s)
break
else:
print('%s是回文字符'%s)
14帶參裝飾器
給裝飾器傳入一個(gè)參數(shù)
from functools import wraps
def record(output):
def decorate(func):
@wraps(func)
def wrapper(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
output(func.__name__,end-start) # 顯示函數(shù)的名字和執(zhí)行時(shí)間
return result
return wrapper
return decorate
因?yàn)檠b飾器實(shí)質(zhì)是就是一個(gè)函數(shù),是一個(gè)被修飾過函數(shù),他與原來未被修飾的函數(shù)是兩個(gè)不同的函數(shù)對(duì)象。 所以,這個(gè)裝飾器丟失了原來函數(shù)對(duì)象的一些屬性,比如:__name__,__doc__等屬性。使用wraps語法糖可以保留這些屬性.
示例:https://blog.csdn.net/weixin_42262081/article/details/119774190
普通裝飾器
import time
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
"""我是 wrapper 的注釋"""
time1 = time.time()
res = func(*args, **kwargs)
time2 = time.time()
print("函數(shù)名:{}".format(func.__name__))
print("入?yún)?args :{}".format(args))
print("入?yún)?kwargs :{}".format(kwargs))
print("返回值:{}".format(res))
print("函數(shù)執(zhí)行耗時(shí):{:.8f}".format(time2 - time1))
return res
return wrapper
14.1多個(gè)裝飾器執(zhí)行順序
@singleton
@log
def add(a,b):
return a + b
如圖當(dāng)一個(gè)函數(shù)有多個(gè)裝飾器時(shí),則先執(zhí)行最里層log的外層代碼,然后執(zhí)行singleton的外層代碼。然后執(zhí)行singleton的內(nèi)層代碼,然后執(zhí)行add函數(shù),然后執(zhí)行l(wèi)og的內(nèi)層代碼。
14.2 不帶參類裝飾器
import time
class Timer:
def __init__(self,func) -> None:
self.func = func
@functools.wraps
def __call__(self, *args, **kwargs):
start = time.time()
ret = self.func(*args, **kwargs)
print(f'Time:{time.time()-start}')
return ret
@Timer
def add(a,b):
time.sleep(1)
return a+b
print(add(2,3))
類裝飾器中使用init函數(shù)初始化,將被裝飾函數(shù)傳遞給類(init方法類似于函數(shù)裝飾器中的最外層函數(shù)用于傳遞被裝飾函數(shù))。然后在call方法中進(jìn)行邏輯處理(call相當(dāng)于函數(shù)裝飾器中的最內(nèi)層函數(shù),用于調(diào)用被裝飾函數(shù))。調(diào)用函數(shù)add(2,3)相當(dāng)于調(diào)用Timer(add)(2,3)所以類裝飾器必須實(shí)現(xiàn)call方法。
14.3帶參類裝飾器
import time
class Timer:
def __init__(self,prefix) -> None:
self.prefix = prefix
def __call__(self, func):
@functools.wraps
def wrapper(*args,**kwargs):
start = time.time()
ret = func(*args, **kwargs)
print(f'{self.prefix}:{time.time()-start}')
return ret
return wrapper
@Timer(prefix = 'curr_time:')
def add(a,b):
time.sleep(1)
return a+b
# 等價(jià)于: add = Timer(prefix = 'curr_time:')(add)
print(add(2,3))
等價(jià)于: add(2,3) = Timer(prefix = 'curr_time:')(add)(2,3)
15快速排序
def quickly_sort(list1):
if len(list1) < 2:
return list1
else:
pivot = list1[0]
small_list = [i for i in list1[1:] if i <= pivot]
big_list = [i for i in list1[1:] if i > pivot]
final_list = quickly_sort(small_list) + [pivot] + quickly_sort(big_list)
return final_list
16數(shù)據(jù)庫1+N查詢
orm模型中1+n查詢解決方法
1.數(shù)據(jù)庫反范式設(shè)計(jì),說直白點(diǎn),就是把表合并,設(shè)計(jì)成冗余表,這可能會(huì)帶來兩個(gè)問題:表中存在大量的重復(fù)數(shù)據(jù)項(xiàng);表中出現(xiàn)大量的空項(xiàng),整個(gè)表格變成一個(gè)稀疏矩陣(sparse matrix)
2.加緩存 把整個(gè)列表頁加上緩存. 這樣 無論是繼續(xù)執(zhí)行1+N次查詢,還是用inner join 1次查詢搞定,都可以.:更新緩存 需要成本,增加了代碼復(fù)雜度;某些場(chǎng)景要求數(shù)據(jù)實(shí)時(shí)性,無法使用緩存
3.把N+1次查詢變成2次查詢:簡單說 先執(zhí)行 select *,category_id from article limited 0,N;然后遍歷結(jié)果列表,取出所有的category_id,去掉重復(fù)項(xiàng),再執(zhí)行一次 select name from category where id in (category id list)
性能優(yōu)化
把子查詢/join查詢 分成兩次,是 高并發(fā)網(wǎng)站數(shù)據(jù)庫調(diào)優(yōu)中非常有效的常見做法,雖然會(huì)花費(fèi)更多的cpu時(shí)間,但是避免了系統(tǒng)的死鎖,提高了并發(fā)響應(yīng)能力;數(shù)據(jù)庫本身處理不了高并發(fā),因?yàn)槲覀冎荒鼙WC單個(gè)數(shù)據(jù)項(xiàng)的操作是原子的,而數(shù)據(jù)庫的查詢是以 列表為基本單元,這是個(gè)天然矛盾,無解;數(shù)據(jù)庫設(shè)計(jì)范式不在web framework能力范圍內(nèi),所以django的ORM 只支持后面兩種做法
Article.ojbects.select_related() 這就是inner join
Article.objects.prefetch_related('category') 這是2次查詢
17django中使用原生sql
一:extra:結(jié)果集修改器,一種提供額外查詢參數(shù)的機(jī)制
二:raw:執(zhí)行原始sql并返回模型實(shí)例
三:直接執(zhí)行自定義Sql
extra方法
Book.objects.filter(publisher__name='廣東人員出版社',price__gt=50)
Book.objects.filter(publisher__name='廣東人員出版社').extra(where=['price>50'])
Book.objects.extra(select={'count':'select count(*) from hello_Book'})
使用raw
Book.objects.raw('select * from hello_Book')
Book.objects.raw("insert into hello_author(name) values('測(cè)試')")
自定義sql
from django.db import connection
cursor=connection.cursor()
cursor.execute("insert into hello_author(name) values('郭敬明')")#插入
cursor.execute('update hello_author set name='abc' where name='bcd'')# 更新
cursor.execute('delete from hello_author where name='abc'')#刪除
cursor.execute('select * from hello_author')# 查詢
raw=cursor.fetchone() #返回結(jié)果行游標(biāo)直讀向前,讀取一條
cursor.fetchall() #讀取所有