工作中碰到的小问题,如何对列表内的字典排序,以及operator.itemgetter介绍。

写搬砖脚本中,需要对每个平台的币价最低报价进行排序,数据格式是字典的,类似[{'gate_ustd_btd': 2020},{'huobi_ustd_btd': 2029},.....]

在操作中,我需要把每个平台的最低报价汇总,然后取出里面的最高报价平台或者最低报价平台。

第一思路是列表套字典,后面发现有序字典套字典也非常合适,只不过有序字典比较消耗内存多点,据说是普通字典内容的一倍。

下一篇随笔准备写一下有序字典

方法是网上找的,自己确实也想不出好的思路,如果特意去写个函数那就太low了。

 

from operator import itemgetter
dict_list = [{"ming": 87}, {"mei": 93}, {"hua": 68}, {"jon": 75}, {"ston": 100}, {"jack": 56}]
mid_dict = {key: value for x in dict_list for key, value in x.items()}
mid_list = sorted(mid_dict.items(), key=itemgetter(1))
fin_list = [{x[0]: x[1]} for x in mid_list]

 为什么我前面说还是直接用有序字典好,这个方法,再实际操作中,

尽然先用字典生成式把列表套字典,转换成字典套字典,

然后用.items取出k,v的元祖形式,用itemgetter取货里面的k或v的值用做sorted函数的key,

最用再用列表生成式返回需要的排序列表,其实整个这样我感觉还是非常麻烦的。如果用字典套字典就免去了列表套字典变成字典套字典的步骤,最后直接生成有序字典就可以了。

我后面准备用orderdict写一个试试,随便介绍一下itemgetter。

查询以及实际操作了一下,如果是普通字典转换为有序字典,还要for循环添加,主要有序字典,不支持字典生成式。

那看来还是列表套字典算了。现在来介绍一下itemgetter,使用的时候感觉一个很好用的取值函数,实际是一个写的很简单类。

初始化设置需要取值的下标,然后就可以通过这个实例化对象调用__call__直接像函数一样使用。

class itemgetter:
    """
    Return a callable object that fetches the given item(s) from its operand.
    After f = itemgetter(2), the call f(r) returns r[2].
    After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
    """
    __slots__ = ('_items', '_call')

    def __init__(self, item, *items):
        if not items:
            self._items = (item,)
            def func(obj):
                return obj[item]
            self._call = func
        else:
            self._items = items = (item,) + items
            def func(obj):
                return tuple(obj[i] for i in items)
            self._call = func

    def __call__(self, obj):
        return self._call(obj)

    def __repr__(self):
        return '%s.%s(%s)' % (self.__class__.__module__,
                              self.__class__.__name__,
                              ', '.join(map(repr, self._items)))

    def __reduce__(self):
        return self.__class__, self._items

 

str00 = 'sidian'
choose = itemgetter(1,2,3)
choose(str00)
('i', 'd', 'i')
choose1 = itemgetter(1,2,3,10)
choose(str00)
('i', 'd', 'i')

 实际操作了一下,还是蛮好用的,选哪个下标,出哪个元素,下标如果超出范围了,还不会报错,不错,不错,就是不能切片取值有点可惜了。






参考资料链接:https://blog.51cto.com/chier11/2415974
posted @ 2019-11-13 00:45  就是想学习  阅读(245)  评论(0编辑  收藏  举报