美文网首页
Python进阶 容器(Collections)

Python进阶 容器(Collections)

作者: FicowShen | 来源:发表于2018-06-13 11:22 被阅读11次



    我们将讨论的是:

    • defaultdict
    • counter
    • deque
    • namedtuple
    • enum.Enum (包含在Python 3.4以上)


    defaultdict

    defaultdict与dict类型不同,你不需要检查key是否存在。

    from collections import defaultdict
    
    colours = (
        ('Yasoob', 'Yellow'),
        ('Ali', 'Blue'),
        ('Arham', 'Green'),
        ('Ali', 'Black'),
        ('Yasoob', 'Red'),
        ('Ahmed', 'Silver'),
    )
    
    favourite_colours = defaultdict(list)
    
    for name, colour in colours:
        favourite_colours[name].append(colour)
    
    print(favourite_colours)
    
    # defaultdict(<type 'list'>,
    #    {'Arham': ['Green'],
    #     'Yasoob': ['Yellow', 'Red'],
    #     'Ahmed': ['Silver'],
    #     'Ali': ['Blue', 'Black']
    # })
    



    当你在一个字典中对一个键进行嵌套赋值时,如果这个键不存在,会触发keyError异常。 defaultdict允许我们用一个聪明的方式绕过这个问题。

    # 问题:
    some_dict = {}
    some_dict['colours']['favourite'] = "yellow"
    
    ## 异常输出:KeyError: 'colours'
    
    
    # 解决方案:
    import collections
    tree = lambda: collections.defaultdict(tree)
    some_dict = tree()
    some_dict['colours']['favourite'] = "yellow"
    
    ## 运行正常
    import json
    print(json.dumps(some_dict))
    
    ## 输出: {"colours": {"favourite": "yellow"}}
    



    lambda简析:

    func=lambda x:x+1
    print(func(1))
    #2
    print(func(2))
    #3
    
    #以上lambda等同于以下函数
    def func(x):
        return(x+1)
    


    counter

    Counter是一个计数器,它可以帮助我们针对某项数据进行计数。

    from collections import Counter
    
    # 统计每个人喜欢多少种颜色
    colours = (
        ('Yasoob', 'Yellow'),
        ('Ali', 'Blue'),
        ('Arham', 'Green'),
        ('Ali', 'Black'),
        ('Yasoob', 'Red'),
        ('Ahmed', 'Silver'),
    )
    
    favs = Counter(name for name, colour in colours)
    print(favs)
    
    ## 输出:
    ## Counter({
    ##     'Yasoob': 2,
    ##     'Ali': 2,
    ##     'Arham': 1,
    ##     'Ahmed': 1
    ##  })
    
    
    
    # 统计一个文件行数
    with open('filename', 'rb') as f:
        line_count = Counter(f)
    print(line_count)
    


    deque

    deque提供了一个双端队列,你可以从头/尾两端添加或删除元素。

    from collections import deque
    
    d = deque()
    d.append('1')
    d.append('2')
    d.append('3')
    
    print(len(d))
    
    ## 输出: 3
    
    print(d[0])
    
    ## 输出: '1'
    
    print(d[-1])
    
    ## 输出: '3'
    
    

    从两端取出(pop)数据:

    d = deque(range(5))
    print(len(d))
    
    ## 输出: 5
    
    d.popleft()
    
    ## 输出: 0
    
    d.pop()
    
    ## 输出: 4
    
    print(d)
    
    ## 输出: deque([1, 2, 3])
    

    可以限制这个列表的大小,当超出你设定的限制时,数据会从对队列另一端被挤出去(pop)。

    d = deque(maxlen=30)  # 现在当你插入30条数据时,最左边一端的数据将从队列中删除。
    

    可以从任一端扩展这个队列中的数据:

    d = deque([1,2,3,4,5])
    d.extendleft([0])
    d.extend([6,7,8])
    print(d)
    
    ## 输出: deque([0, 1, 2, 3, 4, 5, 6, 7, 8])
    


    namedtuple

    namedtuple把元组变成一个针对简单任务的容器。你不必使用整数索引来访问一个namedtuples的数据。
    你可以像字典(dict)一样访问namedtuples,但namedtuples是不可变的。
    namedtuple的每个实例没有对象字典,所以它们很轻量,与普通的元组比,并不需要更多的内存。这使得它们比字典更快。

    from collections import namedtuple
    
    Animal = namedtuple('Animal', 'name age type')
    perry = Animal(name="perry", age=31, type="cat")
    
    print(perry)
    
    ## 输出: Animal(name='perry', age=31, type='cat')
    
    print(perry.name)
    
    ## 输出: 'perry'
    



    你应该使用命名元组来让代码自文档,它们向后兼容于普通的元组,这意味着你可以既使用整数索引,也可以使用名称来访问namedtuple

    from collections import namedtuple
    
    Animal = namedtuple('Animal', 'name age type')
    perry = Animal(name="perry", age=31, type="cat")
    print(perry[0])
    
    ## 输出: perry
    



    可以将一个命名元组转换为字典,方法如下:

    from collections import namedtuple
    
    Animal = namedtuple('Animal', 'name age type')
    perry = Animal(name="Perry", age=31, type="cat")
    print(perry._asdict())
    
    ## 输出: OrderedDict([('name', 'Perry'), ('age', 31), ...
    

    enum.Enum (包含在Python 3.4以上)

    enum模块,存在于Python 3.4以上版本中(同时作为一个独立的PyPI包enum34供老版本使用)。Enums(枚举类型)基本上是一种组织各种东西的方式。

    from collections import namedtuple
    from enum import Enum
    
    class Species(Enum):
        cat = 1
        dog = 2
        horse = 3
        aardvark = 4
        butterfly = 5
        owl = 6
        platypus = 7
        dragon = 8
        unicorn = 9
        # 依次类推
    
        # 但我们并不想关心同一物种的年龄,所以我们可以使用一个别名
        kitten = 1  # (译者注:幼小的猫咪)
        puppy = 2   # (译者注:幼小的狗狗)
    
    Animal = namedtuple('Animal', 'name age type')
    perry = Animal(name="Perry", age=31, type=Species.cat)
    drogon = Animal(name="Drogon", age=4, type=Species.dragon)
    tom = Animal(name="Tom", age=75, type=Species.cat)
    charlie = Animal(name="Charlie", age=2, type=Species.kitten)
    

    相关文章

      网友评论

          本文标题:Python进阶 容器(Collections)

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