day93-排序及random模塊及單例

1random模塊的使用

  1. random.random()函數(shù)是這個(gè)模塊中最常用的方法了,它會(huì)生成一個(gè)隨機(jī)的浮點(diǎn)數(shù),范圍是在0.0~1.0之間
  2. random.uniform(a,b)正好彌補(bǔ)了上面函數(shù)的不足,它可以設(shè)定浮點(diǎn)數(shù)的范圍,一個(gè)是上限,一個(gè)是下限。
  3. random.randint(a,b)隨機(jī)生一個(gè)整數(shù)int類型,可以指定這個(gè)整數(shù)的范圍,同樣有上限和下限值
  4. random.choice(seq)可以從任何序列,比如list列表中,選取一個(gè)隨機(jī)的元素返回,可以用于字符串、列表、元組等
  5. random.shuffle(seq)如果你想將一個(gè)序列中的元素,隨機(jī)打亂的話可以用這個(gè)函數(shù)方法,會(huì)作原地修改。
  6. random.sample(seq,num)可以從指定的序列中,隨機(jī)的截取指定長度的片斷,不作原地修改。

2string模塊的使用

  1. ascii_letters生成所有英文字母(包括大小寫)
  2. digits生成所有數(shù)字
  3. 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() #讀取所有

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容