day93-排序及random模块及单例

1random模块的使用

  1. random.random()函数是这个模块中最常用的方法了,它会生成一个随机的浮点数,范围是在0.0~1.0之间
  2. random.uniform(a,b)正好弥补了上面函数的不足,它可以设定浮点数的范围,一个是上限,一个是下限。
  3. random.randint(a,b)随机生一个整数int类型,可以指定这个整数的范围,同样有上限和下限值
  4. random.choice(seq)可以从任何序列,比如list列表中,选取一个随机的元素返回,可以用于字符串、列表、元组等
  5. random.shuffle(seq)如果你想将一个序列中的元素,随机打乱的话可以用这个函数方法,会作原地修改。
  6. random.sample(seq,num)可以从指定的序列中,随机的截取指定长度的片断,不作原地修改。

2string模块的使用

  1. ascii_letters生成所有英文字母(包括大小写)
  2. digits生成所有数字
  3. ascii_letters+string.digits生成所有英文字母及数字(a-zA-Z0-9)
    random.sample(string.ascii_letters+string.digits,5)从所有字母及数字中随机选出5个字符

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二分查找法

需要先对其排序才能使用二分查找法

def spl(list1, num):
    sear(list1)# 调用二分查找法对其进行排序
    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求素数

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短除法求最大公约数

def gcd(x,y):
    if x>y:
        return gcd(y,x)
    elif y%x ==0:
        return x
    else:
        return gcd(y%x,x)

10随机走台阶

def walk(n):
    #10级台阶,随机走一级,二级,三级,有多少种走法
    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方法

# 创建单例类(法一:使用__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共享属性

# 创建单例类(法二:共享属性)
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使用装饰器

# 创建单例类(法三:装饰器版本)
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带参装饰器

给装饰器传入一个参数

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) # 显示函数的名字和执行时间
            return result
        return wrapper
     return decorate

因为装饰器实质是就是一个函数,是一个被修饰过函数,他与原来未被修饰的函数是两个不同的函数对象。 所以,这个装饰器丢失了原来函数对象的一些属性,比如:__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("函数名:{}".format(func.__name__))
        print("入参 args :{}".format(args))
        print("入参 kwargs :{}".format(kwargs))
        print("返回值:{}".format(res))
        print("函数执行耗时:{:.8f}".format(time2 - time1))
        return res
    return wrapper

14.1多个装饰器执行顺序

@singleton
@log
def add(a,b):
    return a + b

如图当一个函数有多个装饰器时,则先执行最里层log的外层代码,然后执行singleton的外层代码。然后执行singleton的内层代码,然后执行add函数,然后执行log的内层代码。

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函数初始化,将被装饰函数传递给类(init方法类似于函数装饰器中的最外层函数用于传递被装饰函数)。然后在call方法中进行逻辑处理(call相当于函数装饰器中的最内层函数,用于调用被装饰函数)。调用函数add(2,3)相当于调用Timer(add)(2,3)所以类装饰器必须实现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
# 等价于: add = Timer(prefix = 'curr_time:')(add)
print(add(2,3))

等价于: 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数据库1+N查询

orm模型中1+n查询解决方法
1.数据库反范式设计,说直白点,就是把表合并,设计成冗余表,这可能会带来两个问题:表中存在大量的重复数据项;表中出现大量的空项,整个表格变成一个稀疏矩阵(sparse matrix)
2.加缓存 把整个列表页加上缓存. 这样 无论是继续执行1+N次查询,还是用inner join 1次查询搞定,都可以.:更新缓存 需要成本,增加了代码复杂度;某些场景要求数据实时性,无法使用缓存
3.把N+1次查询变成2次查询:简单说 先执行 select *,category_id from article limited 0,N;然后遍历结果列表,取出所有的category_id,去掉重复项,再执行一次 select name from category where id in (category id list)
性能优化
把子查询/join查询 分成两次,是 高并发网站数据库调优中非常有效的常见做法,虽然会花费更多的cpu时间,但是避免了系统的死锁,提高了并发响应能力;数据库本身处理不了高并发,因为我们只能保证单个数据项的操作是原子的,而数据库的查询是以 列表为基本单元,这是个天然矛盾,无解;数据库设计范式不在web framework能力范围内,所以django的ORM 只支持后面两种做法
Article.ojbects.select_related() 这就是inner join
Article.objects.prefetch_related('category') 这是2次查询

17django中使用原生sql

一:extra:结果集修改器,一种提供额外查询参数的机制
二:raw:执行原始sql并返回模型实例
三:直接执行自定义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('测试')")
自定义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() #返回结果行游标直读向前,读取一条
cursor.fetchall() #读取所有

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352