龙空技术网

python基础包functools的cmp_to_key, 比较方法和关键方法-亢保星

数说篮球 94

前言:

今天咱们对“python中cmp的用法”大概比较注意,咱们都需要分析一些“python中cmp的用法”的相关文章。那么小编也在网络上搜集了一些关于“python中cmp的用法””的相关知识,希望大家能喜欢,咱们快快来了解一下吧!

#!/usr/bin/env python#-*- coding:utf-8 -*-"""## 一 functools介绍1、functools 模块可以说主要是为 函数式编程而设计,用于增强函数功能。2、functools模块用以 为可调用对象(callable objects)定义高阶函数或操作。3、functools下面包括:partial                    update_wrapper __doc__                    wraps                    reduce   map reduce                    cmp_to_key                    lru_cache                    singledispatch## 二 cmp_to_key : 字面意思:cmp是比较的意思,key是关键字的意思。## 三 应用场景,是为了兼容以前的版本## 四 方法功能:Transform an old-style comparison function to a key function将老旧风格的对比方法,转变为关键字风格. Used with tools that accept key functions(such as sorted(), min(), max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby()).这个cmp_to_key方法,服务于的方法有sorted方法,min()方法,max()方法等,这些方法都会接受一个关键方法。""""""This function is primarily used as a transition tool for programs being converted from Python 2 which supported the use of comparison functions.1. python2支持比较方法,现在不支持了。2. 需要将对比方法转化为关键方法。2. cmp_to_key 就是将对比方法转为关键方法。""""""A comparison function is any callable that accept two arguments, compares them, and对比方法接受两个参数,然后对比这两个参数returns a negative number for less-than, zero for equality, or a positive number for greater-than. 返回负值代表小于,0代表等于,正值,代表大于。""""""A key function is a callable that accepts one argument and returns another value to be used as the sort key.关键方法,接受一个参数,然后返回另外一个参数进行对比。""""""总结:对比方法接受两个参数,返回正负零。关键方法接受一个参数,返回一个数据用于对比。我们需要研究python中的排序。"""iterable=["张山","李四","九日","利达","lili"]from functools import cmp_to_keyimport localea = sorted(iterable, key=cmp_to_key(locale.strcoll))# sorted 返回一个新的序列old = [5, 2, 3, 1, 4]new = sorted(old)"""结论: 没有改变以前的值,返回了一个新的序列。在某些场景比较重要。""""""直接调用数组内置的方法:"""old.sort()print(old)"""结论:数组对象的sort方法调用比较方便,但是对原数组进行了修改。如果不需要元素组的情况下,这样使用很好。但是需要保留原来数组的情况下,就不很好了。""""""另外数组对象sort方法的一个弊端就是,sort方法只对数组有用。而sorted方法可以接受所有的可迭代对象。"""lists = sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})print(lists)"""不管是list.sort()方法,还是sorted()方法,都有一个关键参数,可以指定一个方法,这个方法会在对比前被调用,来处理可迭代对象的每一个元素,指定用元素的哪个属性进行对比。举个例子:"""lists = sorted("This is a test string from Andrew".split(), key=str.lower)"""这个key参数指定的方法,我们称为关键方法。这个关键方法接受一个参数,返回一个数。这样做比较快,应为这个方法针对每条记录,只被调用一次。""""""下面是一个比较复杂的例子:针对元组"""student_tuples = [    ('john', 'A', 15),    ('jane', 'B', 12),    ('dave', 'B', 10),]lists = sorted(student_tuples, key=lambda student: student[2])"""下面这个例子,针对对象"""class Student:    def __init__(self, name, grade, age):        self.name = name        self.grade = grade        self.age = age    def __repr__(self):        return repr((self.name, self.grade, self.age))student_objects = [    Student('john', 'A', 15),    Student('jane', 'B', 12),    Student('dave', 'B', 10),]lists = sorted(student_objects, key=lambda student: student.age)"""python 中的另外一个模块 Operator(操作模块)上面的关键函数使用非常频繁,python提供了一些内置的关键方法,让使用更加方便。operator模块提供了三个方法:itemgetter(), attrgetter(),methodcaller()"""from operator import itemgetter, attrgetterlists = sorted(student_tuples, key=itemgetter(2))lists = sorted(student_objects, key=attrgetter('age'))"""同时按多个字段进行排序:"""lists = sorted(student_tuples, key=itemgetter(1,2))lsits = sorted(student_objects, key=attrgetter('grade', 'age'))"""升序和降序:"""lists = sorted(student_tuples, key=itemgetter(2), reverse=True)lists = sorted(student_objects, key=attrgetter('age'), reverse=True)"""排序稳定性:当你指定安一个学生的年龄进行排序,两个学生的年龄一样的情况下,该如何排序?复杂排序:允许排序进行叠加。"""data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]lists=sorted(data, key=itemgetter(0))data = [('red', 2), ('blue', 2),('red', 1), ('blue', 1)]lists=sorted(data, key=itemgetter(0))"""结论:python的排序会继承以前的排序。复杂排序:"""# sort on secondary key,根据次要的key进行排序s = sorted(student_objects, key=attrgetter('age'))# now sort on primary key, descending 根据主要的key进行排序,并且降序s = sorted(s, key=attrgetter('grade'), reverse=True)"""这种算法叫做:timsort算法,可以继承之前的排序结果,将多次排序结果给叠加起来。""""""The Old Way Using Decorate-Sort-Undecorate¶在对对象进行排序时候,先需要将对象装修一下,装修完以后进行排序,排序完,再把装修给毁掉。这是一种古老的技术。我们今天已经不需要了,只是祭拜一下这种技术"""decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]decorated.sort()s = [student for grade, i, student in decorated]"""另外一种古老技术:在以前都用cmp参数,进行排序。在python2.4以前,没有sorted()方法,而且list.sort()没有关键方法参数。Py2.x ,要求用户指定比较器。py3.x, 就不需要比较器了。下面是python2.x的写法。"""def numeric_compare(x, y):    return x - y#sorted([5, 2, 4, 1, 3], cmp=numeric_compare)def reverse_numeric(x, y):    return y - x#sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)def cmp_to_key(mycmp):    'Convert a cmp= function into a key= function'    class K:        def __init__(self, obj, *args):            self.obj = obj        def __lt__(self, other):            return mycmp(self.obj, other.obj) < 0        def __gt__(self, other):            return mycmp(self.obj, other.obj) > 0        def __eq__(self, other):            return mycmp(self.obj, other.obj) == 0        def __le__(self, other):            return mycmp(self.obj, other.obj) <= 0        def __ge__(self, other):            return mycmp(self.obj, other.obj) >= 0        def __ne__(self, other):            return mycmp(self.obj, other.obj) != 0    return Klists= sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))"""结论:1. 对字符串进行排序,关键函数是locale.strxfrm();对比函数是: locale.strcoll()2. reverse 参数依旧可以保持排序的稳定性。所谓的稳定性,如果排序的属性相同,则保持以前的排序"""data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]standard_way = sorted(data, key=itemgetter(0), reverse=True)double_reversed = list(reversed(sorted(reversed(data), key=itemgetter(0))))assert standard_way == double_reversed"""3.如果两个对象进行排序,对象需要实现__lt__()方法"""Student.__lt__ = lambda self, other: self.age < other.agelist = sorted(student_objects)"""4.关键方法不必直接依赖于排序对象"""students = ['dave', 'john', 'jane']newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}lists = sorted(students, key=newgrades.__getitem__)

标签: #python中cmp的用法