返回顶部
首页 > 资讯 > 后端开发 > Python >快排实现仿order by多字段排序
  • 922
分享到

快排实现仿order by多字段排序

多字order 2023-01-30 23:01:52 922人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

class OrderBy(object): def __init__(self, sequence, *condition, **extra_condition): """ 排序初始化条件

class OrderBy(object):

    def __init__(self, sequence, *condition, **extra_condition):
        """
        排序初始化条件
        condition为优先排序条件,序列内元素必须为字典类型
        extra_condition为额外的条件因素,当condition不存在时,额外条件才会生效
        :param sequence:
        :param condition:
        :param extra_condition:
        """
        self.array = sequence
        self.condition = list(condition)
        self.extra_condition = extra_condition
        self.has_condition = bool(self.condition)

    def partition(self, left, right, key=None, desc=False, func=None):
        """
        将区间数据进行排序
        分区比较,选择一个基准,根据排序规则,正序:比基准大的放右边,比基准小的放左边
        :param left: 序列区间的开始位置
        :param right: 序列区间的结束位置
        :param key: 对于字典对象,如果指定key,则以key对象比较否则当None值处理
        :param desc: 比较规则为正序或倒序
        :param func: 对值进行处理特殊处理的函数
        :return:
        """
        pivot = self.array[left]
        if isinstance(pivot, dict):
            if key is not None:
                pivot = pivot.get(key)
        if callable(func):
            pivot = func(pivot)
        low = left
        while low < right:
            while low < right:
                _left = self.array[low]
                _right = self.array[right]
                if isinstance(_left, dict):
                    _left = _left.get(key)
                if isinstance(_right, dict):
                    _right = _right.get(key)
                if callable(func):
                    _left = func(_left)
                    _right = func(_right)
                if desc:
                    # 倒序,右边值与基准值都不为空,且右边值小于基准值,左移
                    if _right and pivot and _right < pivot:
                        right -= 1
                    # 倒序,右边值为空,左移
                    elif not _right:
                        right -= 1
                    # 倒序,左边值与基准值都不为空,且左边值大于等于基准值,右移
                    elif _left and pivot and _left >= pivot:
                        low += 1
                    # 倒序,基准值为空,左边值不为空,右移
                    elif _left and not pivot:
                        low += 1
                    else:
                        break
                else:
                    # 正序,基准为空,右边值不为空,左移
                    if _right and not pivot:
                        right -= 1
                    # 正序,右边值与基准都不为空,且右边值大于基准值,左移
                    elif _right and pivot and _right > pivot:
                        right -= 1
                    # 正序,左边值与基准都不为空,且左边值小于等于基准值,右移
                    elif _left and pivot and _left <= pivot:
                        low += 1
                    # 正序,左边值为空,右移
                    elif not _left:
                        low += 1
                    else:
                        break
            if low < right:
                temp = self.array[low]
                self.array[low] = self.array[right]
                self.array[right] = temp
        self.array[left], self.array[low] = self.array[low], self.array[left]
        return low

    def quick_sort(self, left=0, right=None, key=None, desc=False, func=None):
        """
        快速排序算法
        :param left: 区间起始位置
        :param right: 区间结束位置
        :param key: 字典元素使用指定键名值排序
        :param desc: 是否倒序
        :param func: 对于排序值,支持使用函数处理
        :return:
        """
        if right is None:
            right = len(self.array) - 1
        if left < right:
            pivot_position = self.partition(left, right, key, desc, func)
            self.quick_sort(left, pivot_position - 1, key, desc, func)
            self.quick_sort(pivot_position + 1, right, key, desc, func)

    def sort(self, **condition):
        if self.has_condition:
            if not self.condition:
                return
            _condition = self.condition.pop(0)
            if isinstance(_condition, dict):
                condition['key'] = _condition.get('key')
                condition['desc'] = _condition.get('desc', False)
        else:
            condition.update(**self.extra_condition)
        left = condition.get('left')
        right = condition.get('right')
        if not left:
            left = 0
            condition['left'] = left
        if not right:
            right = len(self.array) - 1
            condition['right'] = right
        self.quick_sort(**condition)
        self.sub_sort(left, right, condition.get('key'))

    def sub_sort(self, left, right, key=None, next_index=0):
        """
        标记当前位置begin,及下一个位置end
        当begin位置的元素与end位置元素不等时,当begin!=end - 1时,则进行区间排序
        :param left: 区间起始位置
        :param right: 区间结束位置
        :param key: 当前排序键名
        :param next_index: 下一个条件位置
        :return:
        """
        condition_size = len(self.condition)
        if not condition_size > next_index:
            return
        begin = left
        for end in range(left, right + 1):
            _left = self.array[begin]
            _right = self.array[end]
            if isinstance(_left, dict):
                _left = _left.get(key)
            if isinstance(_right, dict):
                _right = _right.get(key)
            # 当上一个值与当前值不相等,则进入二次排序
            # 当上一个值与当前值相等,且当前位置等于边界位置,且还有下一个排序条件,则进入二次排序
            if _left != _right or (
                    end == right and condition_size >= next_index + 1):
                condition = self.condition[next_index]
                _key = condition.get('key')
                desc = condition.get('desc')
                func = condition.get('func')
                if end == right:
                    _end = end
                else:
                    _end = end - 1
                self.quick_sort(begin, _end, _key, desc, func)
                self.sub_sort(begin, end, _key, next_index + 1)
                begin = end


if __name__ == '__main__':
    a = [dict(age=18, money=200, name='z1'),
         dict(age=16, money=200, name='z2'),
         dict(age=16, money=200, name='z3'),
         dict(age=16, money=100, name='z4'),
         dict(age=16, money=200, name='z5')]
    order_by = OrderBy(a, dict(key='age', desc=False),
                       dict(key='money', desc=True),
                       dict(key='name', desc=True))
    print(a)
    order_by.sort()
    print(a)

--结束END--

本文标题: 快排实现仿order by多字段排序

本文链接: https://lsjlt.com/news/181122.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 快排实现仿order by多字段排序
    class OrderBy(object): def __init__(self, sequence, *condition, **extra_condition): """ 排序初始化条件 ...
    99+
    2023-01-30
    多字 order
  • MySQL中Order By多字段排序规则的示例分析
    小编给大家分享一下MySQL中Order By多字段排序规则的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MySql ...
    99+
    2024-04-02
  • java8 stream多字段排序的实现
    很多情况下sql不好解决的多表查询,临时表分组,排序,尽量用java8新特性stream进行处理 使用java8新特性,下面先来点基础的 List<类> list; ...
    99+
    2024-04-02
  • 详解MySQL中Order By排序和filesort排序的原理及实现
    目录1.Order By原理2.filesort排序算法3.优化排序1.Order By原理 mysql的Order By操作用于排序,并且会有多种不同的排序算法,他们的性能都是不一样的。 假设有一个表,建表的sql如下...
    99+
    2022-08-16
    MySQLOrderBy排序 MySQLfilesort排序 MySQLOrderBy排序filesort排序
  • JSON 数字排序多字段排序介绍
    复制代码 代码如下: //排序数组 function SortBy(field, reverse, primer) { reverse = (reverse) -1 : 1; re...
    99+
    2022-11-15
    JSON 数字排序 多字段排序
  • java8 stream的多字段排序实现(踩坑)
    关于java8 的stream排序用法这里不做多说,这里介绍下曾经在多字段排序时遇到过的一个坑。 需求:需要根据id去分组,然后取出每组中行号最大的一个对象值。 想到可以利用stre...
    99+
    2024-04-02
  • TSQL order by 子句中排序列的多种写法
        Order by 子句用于对结果进行排序,执行顺序位于select子句之后,排序列有4中写法:column_namecolumn_alias,由于o...
    99+
    2024-04-02
  • sql中怎么实现多条件多字段排序
    本篇文章为大家展示了sql中怎么实现多条件多字段排序,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。语句:复制代码 代码如下: select * from ...
    99+
    2024-04-02
  • mysql如何多个字段排序
    mysql中实现多字段排序的方法首先,在命令行中执行命令启动mysql服务;service mysql startmysql服务启动后,在命令行中输入mysql的用户名和密码登录到mysql;mysql -u root&...
    99+
    2024-04-02
  • redis如何做多字段排序
    redis做多字段排序的示例:在redis编辑器中添加以下代码:package com.example.demo;import com.example.demo.common.Constant;import com.example.demo...
    99+
    2024-04-02
  • golang归并排序,快速排序,堆排序的实现
    归并排序 归并排序使用经典的分治法(Divide and conquer)策略。分治法会将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得...
    99+
    2024-04-02
  • Java字符串字段升序排序怎么实现
    你可以使用Java中的`Arrays.sort()`方法来实现字符串字段的升序排序。以下是一个示例代码:```javaimport ...
    99+
    2023-09-14
    Java
  • sql怎么实现两个字段排序
    在SQL中,可以使用ORDER BY子句对查询结果进行排序。可以指定多个字段进行排序,例如:```sqlSELECT * F...
    99+
    2023-09-14
    sql
  • Python3实现快速排序、归并排序、堆
    # -*- coding: utf-8 -*- # @Time : 2019-03-26 16:46 # @Author : Jayce Wong # @ProjectName : leetcode # @Fi...
    99+
    2023-01-31
    快速
  • mysql操作入门(四)-----数据排序(升序、降序、多字段排序)
    已知emp表的内容为 1.升序排序 语法:select 字段名1,字段名2,字段名3 from 表名 (where 条件)order by (字段); 举例:将工资进行升序排序 也可以升序排列字符串,顺序是按照第一...
    99+
    2023-09-17
    mysql 数据库 sql
  • Java的堆排序、快速排序、归并排序怎么实现
    本文小编为大家详细介绍“Java的堆排序、快速排序、归并排序怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java的堆排序、快速排序、归并排序怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。堆排序...
    99+
    2023-06-26
  • 快速排序python实现
      快速排序 快速排序的实现同样使用分治法,它的原理是从序列中选择一个值作为基准值,然后分成比基准值小的序列集合和比基准值小的序列集合和与基准值相等的序列集合。 再将比基准值小的序列集合和比基准值小的序列集合再次进行选择基准值分割,最...
    99+
    2023-01-31
    快速 python
  • python实现快速排序
    def sortList(alist):    alen = len(alist)    if alen == 0:        return alist    if alen > 0:        aitem = alist[a...
    99+
    2023-01-31
    快速 python
  • python 快速排序实现
    import random num_list = []for x in range(30):    num_list.append(random.randint(1, 500))list_len = ...
    99+
    2023-06-02
  • SQL中针对不规范数字order by排序的处理方式
    在操作数据库的时候经常需要order by进行排序,但是有的时候数据并没有很好的格式化导致排序的结果不合我们的心意,如下图:    如果我们要按照value进行排序的话,就会得到上面截图的结果,解决方法有两种: 从数据源下手,把 1 2...
    99+
    2018-07-28
    SQL中针对不规范数字order by排序的处理方式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作