• python基础补充


    一 数据结构和算法

    解压序列赋值给多个变量
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    from collections import deque
    
    # #实现队列,不指定大小则无限添加
    # d=deque(maxlen=3)
    # d.append(1)
    # d.append(2)
    # d.append(3)
    # print(d)
    # d.append(4)
    # print(d)
    # d.appendleft(5)
    # print(d)
    # print(d.pop())
    # print(d.popleft())
    
    def search(file,pattern,max_len=5):
        pre_lines=deque(maxlen=max_len)
        for line in file:
            if pattern in line:
                yield pre_lines,line
            pre_lines.append(line)
    
    if __name__ == '__main__':
        with open('测试文件') as file:
            for pre_l,line in search(file,'Exchange'):
                print('-'*60)
                for i in pre_l:
                    print(i)
                print('匹配行----->',line)
    保留最后n个元素 
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    
    import heapq
    
    nums=[1,2,3,-10,100,30,200,21,9,7]
    print(heapq.nlargest(3,nums))
    print(heapq.nsmallest(3,nums))
    
    
    
    portfolio=[
        {'name':'IBM','shares':100,'price':91.1},
        {'name':'AAPL','shares':50,'price':532.1},
        {'name':'FB','shares':200,'price':21.01},
        {'name':'HPQ','shares':35,'price':32.75},
        {'name':'YHOO','shares':45,'price':16.35},
        {'name':'ACME','shares':75,'price':115.65}
    ]
    
    cheap=heapq.nsmallest(3,portfolio,key=lambda x:x['price'])
    print(cheap)
    
    '''
    如果你想在一个集合中查找最小或最大的N个元素,
    并且N小于集合元素数量, 那么这些函数提供了很好的性能。
    因为在底层实现里面,首先会先将集合数据进行堆
    排序后放入一个列表中
    '''
    
    heapq.heapify(nums)
    print(nums)
    '''
    堆数据结构最重要的特征是heap[0]永远是最小的元素。
    并且剩余的元素可以很 容易的通过调用heap.heappop()方法得到,
    该方法会先将第一个元素弹出来,然后 用下一个最小的元素来取代被弹出元素
    (这种操作时间复杂度仅仅是O(log N),N是堆大小。)比如,如果想要查找最小的3个元素,
    你可以这样做:
    '''
    print(heapq.heappop(nums))
    print(heapq.heappop(nums))
    print(heapq.heappop(nums))
    
    '''
    nlarges(),nsmallest():当要查找的元素个数相对较小时使用
    min(),max():就是要找唯一一个最大的或者最小的值时使用
    sort[items][n:m]:当要查找的元素个数相接近items长度时使用
    '''
    查找最大或最小的n个元素
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    import heapq
    
    class PriotryQueue:
        def __init__(self):
            self._queue=[]
            self._index=0
    
        def push(self,item,priotry):
            heapq.heappush(self._queue,(-priotry,self._index,item))
            self._index+=1
    
        def pop(self):
            return heapq.heappop(self._queue)[-1]
    
    class Item:
        def __init__(self,name):
            self.name=name
    
        def __str__(self):
            return self.name
    
        def __repr__(self):
            # return self.name
            return 'Item({!r})'.format(self.name)
    q=PriotryQueue()
    q.push(Item('镇长'),1)
    q.push(Item('省长'),4)
    q.push(Item('主席'),5)
    q.push(Item('市长'),3)
    q.push(Item('县长'),2)
    
    print(q._queue)
    
    print(q.pop())
    print(q.pop())
    print(q.pop())
    print(q.pop())
    print(q.pop())
    基于heapq实现优先级队列
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    
    '''
    一个字典就是一个键对应一个单值的映射。
    如果你想要一个键映射多个值,那么你就需
    要将这多个值放到另外的容器中,比如列表
    或者集合里面。比如,你可以像下面 这样构造这样的字典:
    '''
    
    people={
        'name':['alex','李杰'],
        'hobby':['play','coding']
    }
    
    project={
        'company':{'IBM':'CTO','Lenovo':'CEO','baidu':'COO','Alibaba':'UFO'},
        'applicant':['小白','lhf','武藤兰']
    }
    
    '''
    选择使用列表还是集合取决于你的实际需求。
    如果你想保持元素的插入顺序就应该使用列表,
    如果想去掉重复元素就使用集合(并且不关心元素的顺序问题)。
    你可以很方便的使用collections模块中的defaultdict来构造这样的字典。             的一个特征是它会自动初始化每个     刚开始对应的值,所以你只需要 关注添加元素操作了。比如:
    '''
    from collections import defaultdict
    d=defaultdict(list)
    d['teacher'].append('alex')
    d['teacher'].append('wupeiqi')
    d['teacher'].append('wuqiqi')
    d['boss'].append('oldboy')
    d['boss'].append('alex')
    
    d_set=defaultdict(set)
    d_set['a'].add(1)
    d_set['a'].add(2)
    d_set['a'].add(3)
    
    print(d,d_set)
    
    #setdefault
    d={}
    
    d.setdefault('a',[]).append(1)
    d.setdefault('a',[]).append(2)
    d.setdefault('a',[]).append(2)
    print(d)
    
    #自己实现一个一键多值字典
    l=[
        ('teacher','alex'),
        ('teacher','lhf'),
        ('teacher','papa'),
        ('boss','alex'),
        ('boss','wupeiqi'),
    ]
    d={}
    for k,v in l:
        if k not in d:
           d[k]=[]
        d[k].append(v)
    print(d)
    
    #用defaultdict实现,更优雅
    d=defaultdict(list)
    for k,v in l:
        d[k].append(v)
    
    print(d)
    实现一个multidict
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    
    from collections import OrderedDict
    d=OrderedDict()
    d['dream1']='先挣他妈一个亿'
    d['dream2']='然后周游全世界'
    d['dream3']='再娶他妈七八个媳妇'
    d['dream4']='洗洗脸,然后梦就醒了'
    
    for key in d:
        print(key,d[key])
    
    # import json
    # print(json.dumps(d))
    
    '''
    OrderedDict内部维护着一个根据键插入顺序排序的双向链表每次当一个新的元素
    插入进来的时候,它会被放到链表的尾部对于一个已经存在的键的重复赋值不会改变
    键的顺序。需要注意的是,一个OrderedDict的大小是一个普通字典的两倍,因为它
    内部维 护着另外一个链表。所以如果你要构建一个需要大量OrderedDict实例的数
    据结构的时候,那么你就得仔细 权衡一下是否使用OrderedDict带来的好处要大过
    额外内存消耗的影响。
    '''
    创建有序字典
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    prices={
        'ACME':45.23,
        'AAPL':612.78,
        'IBM':205.55,
        'HPQ':37.20,
        'FB':10.75
    }
    
    #zip()创建的是只能访问一次的迭代器,下面的max()会报错
    # prices_and_names=zip(prices.values(),prices.keys())
    # min_price=min(prices_and_names)
    # max_price=max(prices_and_names)
    
    #单纯的min(prices)是按照key来取值
    
    
    min_price=min(zip(prices.values(),prices.keys()))
    max_price=max(zip(prices.values(),prices.keys()))
    
    print(min_price)
    print(max_price)
    
    
    print(min(prices,key=lambda k:prices[k]))
    print(max(prices,key=lambda k:prices[k]))
    
    '''
    需要注意的是在计算操作中使用到了(值,键)对。当多个实体
    拥有相同的值的时 候,键会决定返回结果。比如,在执行min()
    和max()操作的时候,如果恰巧最小或 最大值有重复的,那么拥
    有最小或最大键的实体会返回
    '''
    prices={'A':45.23,'Z':45.23}
    
    print(min(zip(prices.values(),prices.keys())))
    字典的运算
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    a={
        'x':1,
        'y':2,
        'z':3,
    }
    
    b={
        'w':1,
        'x':2,
        'y':3,
    }
    
    print(a.keys() & b.keys())
    print(a.keys() - b.keys())
    print(a.items() - b.keys())
    
    
    #生成一个新的字典,去掉某些key
    
    c={key:a[key] for key in a.keys() - {'z','w'}}
    print(c)
    查找俩字典的相同点
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    
    a=[1,5,2,1,9,1,5,10]
    
    #如果想简单去重,可以使用set,但是set是无序的
    # print(set(a))
    
    #如果序列的值都是hashable类型,那么可以简单利用集合或者生成器来解决这个问题
    def dedupe(items):
        seen=set()
        for i in items:
            if i not in seen:
                yield i
                seen.add(i)
    print(list(dedupe(a)))
    
    
    #如果序列元素是不可hashable类型
    a=[
        {'name':'alex','age':18},
        {'name':'alex','age':100},
        {'name':'alex','age':100},
        {'name':'lhf','age':18},
    
    ]
    
    def dedupe(items,key=None):
        seen=set()
        for i in items:
            k=i if not key else key(i)
            if k not in seen:
                yield i
                seen.add(k)
    print(list(dedupe(a,key=lambda k:(k['name'],k['age']))))
    
    #去除文件中相同的内容用第一种方法即可
    去除序列中重复的值且保持顺序
    命名切片
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    from collections import Counter
    words=['if', 'you', 'were', 'a',
           'you,I', 'would', 'never','if',
           'would', 'if']
    # d={}
    # for word in words:
    #     if word not in d:
    #         d[word]=1
    #     else:
    #         d[word]+=1
    # print(d)
    
    word_counts=Counter(words)
    # print(word_counts)
    
    #统计出现频率最高的3个单词
    print(word_counts.most_common(2))
    
    #可以像字典一样取值
    print(word_counts['if'])
    
    #新增单词
    more_words=['if','if']
    for word in more_words:
        word_counts[word]+=1
    
    print(word_counts)
    #或者直接使用
    word_counts.update(more_words)
    print(word_counts)
    
    
    #counter实例可以进行数学运算
    
    a=Counter(words)
    b=Counter(more_words)
    print(a)
    print(b)
    print(a-b)
    print(b-a)
    print(a+b)
    Counter统计出现次数最多的元素
    文件conf.txt内容
    global
            log 127.0.0.1 local2
            daemon
            maxconn 256
            log 127.0.0.1 local2 info
    defaults
            log global
            mode http
            timeout connect 5000ms
            timeout client 50000ms
            timeout server 50000ms
            option  dontlognull
    
    listen stats :8888
            stats enable
            stats uri       /admin
            stats auth      admin:1234
    
    frontend oldboy.org
            bind 0.0.0.0:80
            option httplog
            option httpclose
            option  forwardfor
            log global
            acl www hdr_reg(host) -i www.oldboy.org
            use_backend www.oldboy.org if www
    
    backend www.oldboy.org
            server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
    
    原配置文件
    
    
    deque_test.py内容
    
    from collections import deque
    import re
    
    def conf_dic(f):
        dic={}
        for line in f:
            if re.match('[a-zA-Z]',line):
                key=line
            elif re.match('^ ',line):
                dic.setdefault(key,[]).append(line)
    
        return dic
    
    
    
    if __name__ == '__main__':
        with open('conf.txt',encoding='utf-8') as f:
            dic=conf_dic(f)
    
        for i in dic:
            print('%s' %i,end='')
            for line in dic[i]:
                print(line,end='')
            print('-'*20)
    读取配置文件组成字典
    #_*_coding:utf-8_*_
    __author__ = 'Alex Li'
    from operator import itemgetter
    
    rows=[
        {'fname':'Brian1','lname':'Jones1','uid':1003},
        {'fname':'Brian2','lname':'Jones2','uid':1002},
        {'fname':'Brian3','lname':'Jones3','uid':1001},
        {'fname':'Brian4','lname':'Jones4','uid':1004},
    ]
    # rows_by_uid=sorted(rows,key=lambda rows:rows['uid'])
    # for i in rows_by_uid:
    #     print(i)
    #
    #
    #
    # rows_by_uid=sorted(rows,key=itemgetter('uid'))
    # for i in rows_by_uid:
    #     print(i)
    
    
    rows_by_lfname=sorted(rows,key=itemgetter('lname','fname'))
    print(rows_by_lfname)
    for i in rows_by_lfname:
        print(i)
    字典通过关键字排序
    #_*_coding:utf-8_*_
    __author__ = 'Alex Li'
    
    #要生成列表
    l=[]
    for i in range(6):
       i*=2
       l.append(i)
    print(l)
    
    
    
    y=[i*2 for i in range(6)]
    print(y)
    
    
    def func(n):
        return n+10
    z=[func(i) for i in range(6)]
    print(z)
    
    l=[1,2,3,-1,-10,4,5]
    #过滤掉负数
    l_new=[i for i in l if i >= 0]
    print(l_new)
    列表解析
    #_*_coding:utf-8_*_
    __author__ = 'Alex Li'
    
    
    #生成器,取一次生成一个值,只能next不能回退,因为只有一个
    
    l=[i for i in range(10000000)] #机器卡死
    g=(i for i in range(1000000)) #一秒生成
    g.__next__()
    #next到最后报异常
    
    
    def fib(n1,n2,count=0):
        if count > 10:return
        if count == 0:
            print('',n1,end='')
    
        x=n2
        n2=(n1+n2)
        n1=x
        print(' ',n2,end='')
        count+=1
        fib(n1,n2,count)
    
    
    
    #
    # 0 1 1 2 3 5 8 13 21
    
    # fib(0,1)
    #
    def fib2(max=10):
        n,a,b=0,0,1
        while n < max:
            # x=b
            # b=b+a
            # a=x
            yield b
            a,b=b,a+b
            # print(' ',b,end='')
    
            n+=1
        return 'done'
    
    x=fib2()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    x.__next__()
    
    # while True:
    #     try:
    #         print(x.__next__())
    #     except Exception as e:
    #         print(e)
    #         break
    生成器
    #_*_coding:utf-8_*_
    __author__ = 'Alex Li'
    import time
    
    def consumer(name):
        print('[%s]准备吃包子啦' %name)
        while True:
            baozi=yield
    
            print('包子[%s]来了,被[%s]吃了' %(baozi,name))
    
    
    # c=consumer('alex')
    # c.__next__()
    # c.send('韭菜馅的')
    
    
    def producter():
        c1=consumer('alex')
        c2=consumer('wupeiqi')
        c1.__next__()
        c2.__next__()
        print('开始做包子啦')
        for i in range(10):
            time.sleep(1)
            c1.send(i)
            c2.send(i)
    
    producter()
    
    
    f=open('a.txt')
    f.__next__()
    生成器并行运算
    #_*_coding:utf-8_*_
    __author__ = 'Alex Li'
    name='lhf'
    passwd='123'
    
    def auth(auth_type):
        def inner_auth(func):
            def _wrapper(*args,**kwargs):
                username=input('username: ')
                password=input('passwd: ')
                if auth_type == 'local':
                    if username ==  name and password ==passwd:
                        print('user login successfull')
                        res=func(*args,**kwargs)
    
                    else:
                        exit('log err')
                elif auth_type == 'ldap':
                    print('搞毛线ldap,谁特么会')
    
            return _wrapper
        return inner_auth
    
    
    def index():
        print('welcome to index page')
    
    @auth(auth_type='local')
    def home():
        print("welcome to home page")
    
    @auth(auth_type='ldap')
    def bbs():
        print('welcome to bbs page')
    
    index()
    home()
    bbs()
    带参数装饰器
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    prices={
        'ACME':45.23,
        'AAPL':612.78,
        'IBM':205.55,
        'HPQ':37.20,
        'FB':10.75
    }
    prices_new={key:val for key,val in prices.items() if val > 200}
    print(prices_new)
    从字典中提取子集
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    from collections import namedtuple
    #商品,购买个数,单价
    records=[
        ('mac',2,20000),
        ('lenovo',1,3000),
        ('apple',0,10),
        ('tesla',10,1000000)
    ]
    '''
    命名元组的一个主要用途是将你的代码从下标操作中解脱出来。
    因此,如果你从数 据库调用中返回了一个很大的元组列表,通
    过下标去操作其中的元素,当你在表中添 加了新的列的时候你
    的代码可能就会出错了。但是如果你使用了命名元组,那么就不
    会有这样的顾虑。
    为了说明清楚,下面是使用普通元组的代码:
    '''
    cost=0.0
    for rec in records:
        cost+=rec[1]*rec[2]
        print('商品:%s 购买个数:%s,总价格为:%s' %(rec[0],rec[1],cost))
    
    
    #使用命名元祖后
    sk=namedtuple('Stock',['name','count','price'])
    for rec in records:
        s=sk(*rec)
        print(s.count*s.price)
    
    p=namedtuple('People',['name','gender','age'])
    l=['alex','femal',18]
    p1=p(*l)
    print(p1)
    print(p1.name)
    print(p1.age)
    print(p1.gender)
    
    '''
    命名元组另一个用途就是作为字典的替代,
    因为字典存储需要更多的内存空间。如果
    你需要构建一个非常大的包含字典的数据结构,
    那么使用命名元组会更加高效。但 是需要注意的是,
    不像字典那样,一个命名元组是不可更改的。比如:
    '''
    p=namedtuple('People',['name','gender','age'])
    l=['alex','femal',18]
    p1=p(*l)
    print(p1.name)
    # p1.name='sb'#报错,不可修改
    p1=p1._replace(name='sb')#需要重新赋值给p1
    print(p1.name)
    
    #可以新建一个函数,弥补必须使用_replace才能修改元素的缺点
    p=namedtuple('People',['name','gender','age'])
    p1=p('','',None)
    def dict_to_stock(s):
        return p1._replace(**s)
    
    print(dict_to_stock({'name':'alex','gender':'f','age':18}))
    print(dict_to_stock({'name':'sb','gender':'f','age':18}))
    nametuple命名元组
  • 相关阅读:
    Session攻击(会话劫持+固定)与防御
    console调试命令
    javascript获取当前url
    搞不清FastCgi与PHP-fpm之间是个什么样的关系
    MySQL基本语句优化10个原则
    PHP获取类名及所有函数名
    js闭包
    字段、方法、属性
    python面向对象之类成员修饰符
    实现Python代码发送邮件
  • 原文地址:https://www.cnblogs.com/llhtjwq/p/8306411.html
Copyright © 2020-2023  润新知