美文网首页
Python之codebook笔记

Python之codebook笔记

作者: 鹊南飞_ | 来源:发表于2020-01-16 14:22 被阅读0次

    1. 解压序列赋值给多个变量

    任何的序列(或者可迭代对象)可以通过一个简单的赋值语句解压并赋值给多个变量。
    唯一的前提就是变量的数量必须跟序列元素的数量是一样的

    p = [4, 5, 6]
    a, b, c = p
    print(a, b, c)
    
    4 5 6
    

    2. 解压可迭代对象给多个变量

    使用Python的星号(*)解决这个问题
    解压出来的变量永远是列表类型

    record = (1, 2, 3, 4, 5)
    first, *number, end = record
    print(first, number, end)
    
    1 [2, 3, 4] 5
    

    3. 保留最后N个元素

    使用collections.deque

    from collections import deque
    # 构建一个固定长度为3的队列
    q = deque(maxlen=3)
    q.append(1)
    q.append(2)
    q.append(3)
    q
    
    deque([1, 2, 3])
    
    q.append(4)
    q
    
    deque([2, 3, 4])
    

    4. 保留最大或最小的N的元素

    使用heapq模块的两个函数,nlargest()和nsmallest()

    import heapq
    nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
    print(heapq.nlargest(3, nums))
    print(heapq.nsmallest(3, nums))
    print(max(nums))
    print(min(nums))
    
    
    [42, 37, 23]
    [-4, 1, 2]
    42
    -4
    
    
    # 可以接受关键字参数,用于更复杂的数据结构
    portfolio = [
        {'name': 'IBM', 'shares': 100, 'price': 91.1},
        {'name': 'AAPL', 'shares': 50, 'price': 543.22},
        {'name': 'FB', 'shares': 200, 'price': 21.09},
        {'name': 'HPQ', 'shares': 35, 'price': 31.75},
        {'name': 'YHOO', 'shares': 45, 'price': 16.35},
        {'name': 'ACME', 'shares': 75, 'price': 115.65}
    ]
    cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
    expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
    print(cheap)
    print(expensive)
    
    
    [{'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}]
    [{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}]
    
    

    当要查找的元素个数相对比较小的时候,heapq.nsmallest()和heapq.nlargest()是很合适的
    如果只是想找唯一的最大或最小就使用max()和min()函数
    如果N的大小和集合大小接近的时候,则使用切片操作会更快一点sorted(items)[:N]或者sorted(items)[-N:]

    5. 实现一个优先级队列

    使用heapq模块的heappush()和heappop()

    import heapq
    
    class PriorityQueue:
        def __init__(self):
            self._queue = []
            self._index = 0
    
        def push(self, item, priority):
            heapq.heappush(self._queue, (-priority, 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 __repr__(self):
            return 'Item({!r})'.format(self.name)
    
    
    
    q = PriorityQueue()
    q.push(Item('foo'), 1)
    q.push(Item('bar'), 4)
    q._queue
    
    
    [(-4, 1, Item('bar')), (-1, 0, Item('foo'))]
    
    
    q.pop()
    
    
    Item('bar')
    
    

    6. 字典中的键映射多个值

    一个字典就是一个键对应一个单值的映射。
    如果你想要一个值映射多个值,需要这多个值放到另外的容器中

    d = {
        'a' : [1, 2, 3]
    }
    d
    
    
    {'a': [1, 2, 3]}
    
    
    d = {
        'a' : {1, 2, 3}
    }
    d
    
    
    {'a': {1, 2, 3}}
    
    
    # 或者可以使用collections.defaultdict
    from collections import defaultdict
    d = defaultdict(list)
    d['a'].append(1)
    d['a'].append(2)
    d['b'].append(4)
    d
    
    
    defaultdict(list, {'a': [1, 2], 'b': [4]})
    
    
    d = defaultdict(set)
    d['a'].add(1)
    d['a'].add(2)
    d['b'].add(4)
    d
    
    
    defaultdict(set, {'a': {1, 2}, 'b': {4}})
    
    

    7. 字典排序

    使用collections模块OrderedDict类
    在迭代的时候保存元素被插入时的顺序
    注意,3.6 的 dict 是有序的,在此版本之前皆是无序

    from collections import OrderedDict
    d = OrderedDict()
    d['foo'] = 1
    d['bar'] = 2
    d['spam'] = 3
    d['aok'] = 4
    for key in d:
        print(key, d[key])
    
    
    foo 1
    bar 2
    spam 3
    aok 4
    
    
    d = {}
    d['foo'] = 1
    d['bar'] = 2
    d['spam'] = 3
    d['aok'] = 4
    for key in d:
        print(key, d[key])
    
    
    foo 1
    bar 2
    spam 3
    aok 4
    
    

    8. 字典的运算(求最大值,最小值,排序等等)

    prices = {
        'ACME': 45.23,
        'AAPL': 612.78,
        'IBM': 205.55,
        'HPQ': 37.20,
        'FB': 10.75
    }
    
    

    直接使用max函数,是对字典的key值进行操作
    可以使用zip函数将键和值反转过来
    注意:zip()函数创建的是一个只能访问一次的迭代器

    min_price = min(zip(prices.values(), prices.keys()))
    max_price = max(zip(prices.values(), prices.keys()))
    min_price, max_price
    
    
    ((10.75, 'FB'), (612.78, 'AAPL'))
    
    

    9. 查找两字典的相同点

    可以简单的使用字典的keys()或者items()方法返回结果上执行集合操作

    a = {
        'x' : 1,
        'y' : 2,
        'z' : 3
    }
    
    b = {
        'w' : 1,
        'x' : 11,
        'y' : 2
    }
    
    
    a.keys() & b.keys()
    
    
    {'x', 'y'}
    
    
    a.items() & b.items()
    
    
    {('y', 2)}
    
    

    字典的keys()方法返回一个展现键集合的键视图对象
    字典的items()方法返回一个包含(键,值)对的元素视图对象

    10. 删除序列相同元素并保持排序

    def dedupe(items):
        seen = set()
        for item in items:
            if item not in seen:
                print('item is {}, seen is {}'.format(item, seen))
                yield item
                seen.add(item)
    
    
    a = [1,3,4,5,6,1,3,5]
    list(dedupe(a))
    
    
    item is 1, seen is set()
    item is 3, seen is {1}
    item is 4, seen is {1, 3}
    item is 5, seen is {1, 3, 4}
    item is 6, seen is {1, 3, 4, 5}
    
    
    [1, 3, 4, 5, 6]
    
    
    def dedupe(items, key=None):
        seen = set()
        for item in items:
            val = item if key is None else key(item)
            print('item {} value {}'.format(item, val))
            if val not in seen:
                yield item
                seen.add(val)
    
    
     a = [ {'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
    list(dedupe(a, key = lambda d:(d['x'],d['y'])))
    
    
    item {'x': 1, 'y': 2} value (1, 2)
    item {'x': 1, 'y': 3} value (1, 3)
    item {'x': 1, 'y': 2} value (1, 2)
    item {'x': 2, 'y': 4} value (2, 4)
    
    
    [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
    
    

    匿名函数: 将创建好的匿名函数通过一个变量去接收,使用变量去调用函数

    简单使用set()方法构建一个集合,也可以实现消除重复元素,但是元素位置会被打乱

    11. 命名切片

    给切片命名,使得代码更加清晰可读
    
    record = '....................100 .......513.25 ..........'
    # 使用slice切片,并命名
    SHARES = slice(20, 23)
    PRICE = slice(31, 37)
    cost = int(record[SHARES]) * float(record[PRICE])
    cost
    
    
    51325.0
    
    

    12. 序列中出现次数最多的元素

    collctions.Counter类,里面的most_common()
    
    words = [
        'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
        'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
        'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
        'my', 'eyes', "you're", 'under'
    ]
    from collections import Counter
    word_counts = Counter(words)
    # 出现频率最高的3个单词
    top_three = word_counts.most_common(3)
    print(top_three)
    
    
    [('eyes', 8), ('the', 5), ('look', 4)]
    
    

    13. 通过某个关键字排序一个字典列表

    operator.itemgetter函数
    
    rows = [
        {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
        {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
        {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
        {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
    ]
    from operator import itemgetter
    rows_by_fname = sorted(rows, key=itemgetter('fname'))
    rows_by_uid = sorted(rows, key=itemgetter('uid'))
    print(rows_by_fname)
    print(rows_by_uid)
    
    
    [{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
    [{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
    
    
    min(rows, key = itemgetter('uid'))
    
    
    {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
    
    

    14. 排序不支持原生比较的对象

    operator.attagetter()函数
    
    class User:
        def __init__(self, user_id):
            self.user_id = user_id
    
        def __repr__(self):
            return 'User({})'.format(self.user_id)
        
    users = [User(23), User(3), User(99)]
    from operator import attrgetter
    sorted(users, key=attrgetter('user_id'))
    
    
    [User(3), User(23), User(99)]
    
    

    15. 通过某个字段将记录分组

    itertools.groupby()
    

    16. 过滤序列元素

    最简单的办法是列表推导
    

    17. 从字典中提取子集

    最简单的办法是字典推导
    
    prices = {
        'ACME': 45.23,
        'AAPL': 612.78,
        'IBM': 205.55,
        'HPQ': 37.20,
        'FB': 10.75
    }
    p1 = {key: value for key, value in prices.items() if value > 200}
    print(p1)
    
    
    {'AAPL': 612.78, 'IBM': 205.55}
    
    
    tech_names = {'AAPL', 'IBM', 'HPQ'}
    p2 = {key: value for key, value in prices.items() if key in tech_names}
    print(p2)
    
    
    {'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.2}
    
    

    18. 映射名称到序列元素

    collections.namedtuple()函数
    

    19. 转换并同时计算数据

    nums = [1, 2, 3, 4, 5]
    s = sum(x * x for x in nums)
    s
    
    
    55
    
    
    s = sum((x * x for x in nums)) # 显示的传递一个生成器表达式对象
    s=  sum((x * x for x in nums) # 更加优雅的实现方式,省略了括号
    
    
    portfolio = [
        {'name':'GOOG', 'shares': 50},
        {'name':'YHOO', 'shares': 75},
        {'name':'AOL', 'shares': 20},
        {'name':'SCOX', 'shares': 65}
    ]
    min_shares = min(s['shares'] for s in portfolio)
    min_shares
    
    
    20
    
    

    20. 合成多个字典或映射

    使用collections.ChainMap类

    相关文章

      网友评论

          本文标题:Python之codebook笔记

          本文链接:https://www.haomeiwen.com/subject/olpfzctx.html