如何使用相同的方法快速通过不同属性排序对象列表?

发布于 2025-01-29 18:29:23 字数 1581 浏览 1 评论 0原文

我的班级如下:

class Member:
  def __init__(self, name, zip, hire_date, birth_date):
    self.id = id
    self.name = name
    self.zip = zip
    self.hire_date = hire_date
    self.birth_date = birth_date

  def get_name(self):
    return self.name

  def get_birth_date(self):
    return self.birth_date

  def get_hire_date(self):
    return self.hire_date

  def get_zip_code(self):
    return self.zip

我需要根据邮政编码,名称,berth_date和hire_date快速对此类对象进行列表。我可以使用各个排序方法来实现这些方法。例如,按邮政编码进行快速排序:

def partition(array, begin, end):
    pivot = begin
    for i in range(begin+1, end+1):
        if array[i].get_zip_code() <= array[begin].get_zip_code():
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot



def quicksort(array, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

这可以正常工作。但是现在如何使同样的方法在所有属性上起作用;理想情况下,通过将附加参数传递到QuickSort()定义要排序的属性。我还希望不直接调用对象属性,而是通过使用getter方法。

这是按邮政编码排序后输出的

Name    Zip Hire Date   Birth Date
Cosmo Kramer 111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld 223-212 2017-06-01 1981-06-15
John Wayne 323-212 2018-06-01 1962-06-17

My class is as below:

class Member:
  def __init__(self, name, zip, hire_date, birth_date):
    self.id = id
    self.name = name
    self.zip = zip
    self.hire_date = hire_date
    self.birth_date = birth_date

  def get_name(self):
    return self.name

  def get_birth_date(self):
    return self.birth_date

  def get_hire_date(self):
    return self.hire_date

  def get_zip_code(self):
    return self.zip

I have need to quick sort a list of this class object based on zip code, name, birth_date and hire_date. I can achieve these using individual sort methods. For example, quick sort by zip code:

def partition(array, begin, end):
    pivot = begin
    for i in range(begin+1, end+1):
        if array[i].get_zip_code() <= array[begin].get_zip_code():
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot



def quicksort(array, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

This works fine. But now how do I make the same method work on all attributes; ideally by passing an additional argument to quicksort() defining the attribute to sort on. I also wish to not call object attributes directly but by using getter methods.

This is output after sorting by zip code

Name    Zip Hire Date   Birth Date
Cosmo Kramer 111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld 223-212 2017-06-01 1981-06-15
John Wayne 323-212 2018-06-01 1962-06-17

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

看透却不说透 2025-02-05 18:29:24

请参阅Python自己的分类功能的实现:

def identity(x):
    return x

def partition(array, begin, end, key):
    pivot = begin
    for i in range(begin+1, end+1):
        if key(array[i]) <= key(array[begin]):
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, begin=0, end=None, key=identity):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end, key)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

用法:

quicksort(list_of_member, key=Member.get_name)
quicksort(list_of_member, key=Member.get_zip_code)

Refer to the implementation of Python's own sorting function:

def identity(x):
    return x

def partition(array, begin, end, key):
    pivot = begin
    for i in range(begin+1, end+1):
        if key(array[i]) <= key(array[begin]):
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, begin=0, end=None, key=identity):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end, key)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

Usage:

quicksort(list_of_member, key=Member.get_name)
quicksort(list_of_member, key=Member.get_zip_code)
笑看君怀她人 2025-02-05 18:29:24

您可以通过定义同类中的另一种方法来实现这一目标:

class Metric:
    b_date = "birth_date"
    h_date = "hire_date"
    zip_code = "zip_code"
    name = "name"


class Member:
    def __init__(self, name, zip, hire_date, birth_date):
        self.id = id
        self.name = name
        self.zip = zip
        self.hire_date = hire_date
        self.birth_date = birth_date

    def get_name(self):
        return self.name

    def get_birth_date(self):
        return self.birth_date

    def get_hire_date(self):
        return self.hire_date

    def get_zip_code(self):
        return self.zip

    def get_metric_value(self, metric):
        if metric == Metric.b_date:
            return self.get_birth_date()
        elif metric == Metric.h_date:
            return self.get_hire_date()
        elif metric == Metric.zip_code:
            return self.get_zip_code()
        elif metric == Metric.name:
            return self.get_name()

def partition(array, begin, end, metric):
    pivot = begin
    for i in range(begin+1, end+1):
        if array[i].get_metric_value(metric) <= array[begin].get_metric_value(metric):
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, metric, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end, metric)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

quicksort(array, Metric.zip_code)  # or any other metric ...

You can achieve this by defining another method inside your class:

class Metric:
    b_date = "birth_date"
    h_date = "hire_date"
    zip_code = "zip_code"
    name = "name"


class Member:
    def __init__(self, name, zip, hire_date, birth_date):
        self.id = id
        self.name = name
        self.zip = zip
        self.hire_date = hire_date
        self.birth_date = birth_date

    def get_name(self):
        return self.name

    def get_birth_date(self):
        return self.birth_date

    def get_hire_date(self):
        return self.hire_date

    def get_zip_code(self):
        return self.zip

    def get_metric_value(self, metric):
        if metric == Metric.b_date:
            return self.get_birth_date()
        elif metric == Metric.h_date:
            return self.get_hire_date()
        elif metric == Metric.zip_code:
            return self.get_zip_code()
        elif metric == Metric.name:
            return self.get_name()

def partition(array, begin, end, metric):
    pivot = begin
    for i in range(begin+1, end+1):
        if array[i].get_metric_value(metric) <= array[begin].get_metric_value(metric):
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, metric, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end, metric)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

quicksort(array, Metric.zip_code)  # or any other metric ...
半暖夏伤 2025-02-05 18:29:23

添加另一个参数,该参数指示要排序,或者只使用内置sort()方法,该方法执行相同的事情:

class Member:
    def __init__(self, name, zip, hire_date, birth_date):
        self.id = id
        self.name = name
        self.zip = zip
        self.hire_date = hire_date
        self.birth_date = birth_date

    def get_name(self):
        return self.name

    def get_birth_date(self):
        return self.birth_date

    def get_hire_date(self):
        return self.hire_date

    def get_zip_code(self):
        return self.zip

    # Define how to print a Member
    def __str__(self):
        return f'{self.name:15} {self.zip} {self.hire_date} {self.birth_date}'

def partition(array, key, begin, end):
    pivot = begin
    for i in range(begin+1, end+1):
        if key(array[i]) <= key(array[begin]): # use key for comparison
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, key, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, key, begin, end):
        if begin >= end:
            return
        pivot = partition(array, key, begin, end)
        _quicksort(array, key, begin, pivot-1)
        _quicksort(array, key, pivot+1, end)
    return _quicksort(array, key, begin, end)

def display(L):
    print('Name            Zip     Hire Date  Birth Date')
    for item in L:
        print(item)
    print()

L =[Member('Cosmo Kramer','111-222','2019-06-01','1979-08-12'),
    Member('George Costanza','131-212','2016-06-01','1980-08-12'),
    Member('Jerry Seinfeld','223-212','2017-06-01','1981-06-15'),
    Member('John Wayne','323-212','2018-06-01','1962-06-17')]

quicksort(L,Member.get_hire_date)
display(L)
quicksort(L,Member.get_birth_date)
display(L)
# Using built-in sort()
L.sort(key=Member.get_name)
display(L)

输出:输出:

Name            Zip     Hire Date  Birth Date
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld  223-212 2017-06-01 1981-06-15
John Wayne      323-212 2018-06-01 1962-06-17
Cosmo Kramer    111-222 2019-06-01 1979-08-12

Name            Zip     Hire Date  Birth Date
John Wayne      323-212 2018-06-01 1962-06-17
Cosmo Kramer    111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld  223-212 2017-06-01 1981-06-15

Name            Zip     Hire Date  Birth Date
Cosmo Kramer    111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld  223-212 2017-06-01 1981-06-15
John Wayne      323-212 2018-06-01 1962-06-17

Add another parameter that indicates the key to sort on, or just use the built-in sort() method which does the same thing:

class Member:
    def __init__(self, name, zip, hire_date, birth_date):
        self.id = id
        self.name = name
        self.zip = zip
        self.hire_date = hire_date
        self.birth_date = birth_date

    def get_name(self):
        return self.name

    def get_birth_date(self):
        return self.birth_date

    def get_hire_date(self):
        return self.hire_date

    def get_zip_code(self):
        return self.zip

    # Define how to print a Member
    def __str__(self):
        return f'{self.name:15} {self.zip} {self.hire_date} {self.birth_date}'

def partition(array, key, begin, end):
    pivot = begin
    for i in range(begin+1, end+1):
        if key(array[i]) <= key(array[begin]): # use key for comparison
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, key, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, key, begin, end):
        if begin >= end:
            return
        pivot = partition(array, key, begin, end)
        _quicksort(array, key, begin, pivot-1)
        _quicksort(array, key, pivot+1, end)
    return _quicksort(array, key, begin, end)

def display(L):
    print('Name            Zip     Hire Date  Birth Date')
    for item in L:
        print(item)
    print()

L =[Member('Cosmo Kramer','111-222','2019-06-01','1979-08-12'),
    Member('George Costanza','131-212','2016-06-01','1980-08-12'),
    Member('Jerry Seinfeld','223-212','2017-06-01','1981-06-15'),
    Member('John Wayne','323-212','2018-06-01','1962-06-17')]

quicksort(L,Member.get_hire_date)
display(L)
quicksort(L,Member.get_birth_date)
display(L)
# Using built-in sort()
L.sort(key=Member.get_name)
display(L)

Output:

Name            Zip     Hire Date  Birth Date
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld  223-212 2017-06-01 1981-06-15
John Wayne      323-212 2018-06-01 1962-06-17
Cosmo Kramer    111-222 2019-06-01 1979-08-12

Name            Zip     Hire Date  Birth Date
John Wayne      323-212 2018-06-01 1962-06-17
Cosmo Kramer    111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld  223-212 2017-06-01 1981-06-15

Name            Zip     Hire Date  Birth Date
Cosmo Kramer    111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld  223-212 2017-06-01 1981-06-15
John Wayne      323-212 2018-06-01 1962-06-17
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文