• [PY3]——字典排序问题总结—(zip()函数、OrderedDict、itemgetter函数)


    问题

    怎样在数据字典中执行一些计算操作(从而实现求最小值、最大值或排序等等)?

    如何能根据某个或某几个字典字段来排序一个字典列表?

    如何创建一个字典,并且在迭代或序列化这个字典的时候能够控制元素的顺序?

    解决方案

    zip( )函数

    operator模块的itemgetter函数

    OrderedDict 有序字典

    zip( )

    1. 为了对字典值执行计算操作,通常需要使用zip( )函数先将键和值反转过来

    2. 从而我们能将zip和sorted( )、max( )、min( )函数结合使用,来实现排列字典数据

    prices = {
        'ACME': 37.20,
        'AAPL': 612.78,
        'IBM': 205.55,
        'HPQ': 37.20,
        'FB': 10.75
    }
    
    print(min(prices),max(prices))  #直接对字典执行普通的数学运算,其只会对key操作
    AAPL IBM
    
    print(min(prices.values()),max(prices.values())) #可通过字典的values函数解决,但输出时只能看到values 
    10.75 612.78
    
    print(min(prices,key=lambda x:prices[x])) #可通过min/max的key属性函数解决,但输出同样不好看 
    FB
    
    print(min(zip(prices.values(),prices.keys())))    #先通过zip()将字典”反转”为(value,key)的元组序列 
    (10.75, 'FB')
    
    print(sorted(zip(prices.values(),prices.keys())))   #若恰巧出现values相同的情况,则根据key的排序结果返回  
    [(10.75, 'FB'), (37.2, 'ACME'), (37.2, 'HPQ'), (205.55, 'IBM'), (612.78, 'AAPL')]

    3. 执行这些计算的时候,需要注意的是zip( )函数创建的是一个只能访问一次的迭代器

    prices_and_names=zip(prices.values(),prices.keys())
    
    print(max(prices_and_names))
    (612.78, 'AAPL')
    
    print(max(prices_and_names))   #第二次再用就报错了
    ValueError: max() arg is an empty sequence

    operator模块的itemgetter函数

    1. sorted(rows,key=itemgetter)

    from operator import 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}
    ]
    
    #根据任意的字典字段key来排序
    rows_by_uid=sorted(rows,key=itemgetter('uid'))
    print(rows_by_uid)
    [{'uid': 1001, 'lname': 'Cleese', 'fname': 'John'}, {'uid': 1002, 'lname': 'Beazley', 'fname': 'David'}, {'uid': 1003, 'lname': 'Jones', 'fname': 'Brian'}, {'uid': 1004, 'lname': 'Jones', 'fname': 'Big'}]
    
    #也支持多个 keys
    rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))
    print(rows_by_lfname)
    [{'uid': 1002, 'lname': 'Beazley', 'fname': 'David'}, {'uid': 1001, 'lname': 'Cleese', 'fname': 'John'}, {'uid': 1004, 'lname': 'Jones', 'fname': 'Big'}, {'uid': 1003, 'lname': 'Jones', 'fname': 'Brian'}]
    
    #应当注意,以上两个排序语句等价于:
    rows_by_fname = sorted(rows, key=lambda r: r['uid'])
    rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
    #但使用 itemgetter() 方式会运行的稍微快点

    2. itemgetter同样适用于min( )和max( )等函数

    rows_min_uid=min(rows, key=itemgetter('uid'))
    print(rows_min_uid)
    {'uid': 1001, 'lname': 'Cleese', 'fname': 'John'}

    OrderedDict 有序字典

    1. 为了能控制一个字典中元素的顺序,你可以使用 collections 模块中的 OrderedDict 类。 在迭代操作的时候它会保持元素被插入时的顺序

    from collections import OrderedDict
    
    d={}
    d[0]=3;d[6]=1;d[3]=1    //仔细看插入顺序
    for k,v in d.items():
        print(k,v)          //输出的时候dict字典会按照key顺序来排序
    0 3
    3 1
    6 1
    
    od=OrderedDict()
    od[0]=3;od[6]=1;od[3]=1   //但同样的插入顺序下
    for k,v in od.items():
        print(k,v)            //OrdereDict会保持插入顺序
    0 3
    6 1
    3 1

    2. 需要注意的是,一个 OrderedDict 的大小是一个普通字典的两倍,因为它内部维护着另外一个链表,要注意内存消耗问题

  • 相关阅读:
    python os
    [BZOJ2887] 旅行
    UVA1104 Chips Challenge
    CF364E Empty Rectangles
    CF1408H Rainbow Triples
    CF1214G Feeling Good
    CF506E Mr. Kitayuta's Gift
    采用Canal监听mysql数据库变化
    Java8 ParallelStream
    Java8 方法引用
  • 原文地址:https://www.cnblogs.com/snsdzjlz320/p/7152531.html
Copyright © 2020-2023  润新知