我试图找出是否有更快的方法来排序和修改python中的列表,除了原生的"sorted"函数.

100 我有多个来自自定义类的对象,我想根据它们的Z属性对它们进行排序,Z属性是一个整数值.理想情况下,对象存储在字典中,但如果性能更好的话,列表也可以.它们将以每秒60次的速度更新.并且在任何帧,任何对象的任何Z属性都可能改变,并且需要相应地对列表进行排序.可能会不时地添加或删除对象,但优化尤其针对对象的Z值更改后的列表/字典排序.

我还可以一次更新列表中的一个对象或一个Z值更改,并且只更改该对象在排序中的位置,如果有快速的方法这样做的话.

我问heaps个是不是一个很好的解决方案,但他们不是. 在那个链接的帖子中,我得到了关于B树、AVL树、红黑树、跳过列表和Python排序容器的建议,但我不确定它们是否对我的特定用例有帮助.

我try 在列表中循环单个对象,直到它到达正确的Z位置,但这种方法也比使用原生sorted()命令对整个列表进行排序要慢得多.我在下面粘贴了该测试的示例代码.

有没有人知道有没有更快、更有效的方法来对我的特定用例进行排序?如果是这样的话,基本实现的示例代码是什么?

示例代码(this code is merely for performance testing and is not meant to be fully optimized):

import  random
from statistics import mean
import time


class Object:
    def __init__(self):
        self.Z = random.randint(0,1000000)
    def __repr__(self):
        return str(self.Z)
    def __str__(self):
        return str(self.Z)

# Creating a sorted list first:
list_base = [Object() for i in range(10000)]
sorted_list = sorted(list_base, key = lambda name: name.Z)

# New object that will be added to the beginning of the list with a higher Z value than the others:
new_obj = Object()
new_obj.Z = 1000001

# Store the timing results in lists for performance testing:
results_native = []
results_custom = []

# Run performance test multiple time:
for i in range(200):
    # inserting new object at the beginning of the list:
    # current index:
    index = 0
    sorted_list.insert(index, new_obj)
    # Sort method native:
    start_time = time.time()
    sorted_list = sorted(sorted_list, key = lambda name: name.Z)
    finish_time_1 = time.time() - start_time

    results_native.append(finish_time_1)
    # Inserting the object back to the beginning of the list to repeat the test:
    sorted_list.insert(0, sorted_list.pop(-1))

    # Sort method Custom looping:
    start_time = time.time()
    index += 1
    while not index >= len(sorted_list) and sorted_list[index].Z <= new_obj.Z:
        index += 1
    sorted_list.insert(index - 1, sorted_list.pop(0))
    finish_time_2 = time.time() - start_time

    results_custom.append(finish_time_2)

print("Native finish time:", mean(results_native))
print("Custom loop finish time:", mean(results_custom))

推荐答案

我测试并比较了平分和分类的集装箱. 以下是1000项测试的中值测试结果:

Native finish time: 0.0036494266986846925
Bisect finish time: 3.2123804092407225e-05
Sorted Container finish time: 1.5070676803588867e-05

Sorted Container lists具有最高性能的排序过程,因此我考虑了这篇文章的解决方案!

我用来比较性能的代码如下:

import numpy as np
import bisect
from sortedcontainers import SortedList


import  random
from statistics import mean
import time

class Object:
    def __init__(self):
        self.Z = random.randint(0,1000000)
    def __repr__(self):
        return str(self.Z)
    def __str__(self):
        return str(self.Z)

# Creating a sorted list first:
list_base = [Object() for i in range(10000)]
container_sorted_list = SortedList(list_base, key=lambda x: x.Z)

# New object that will be added to the beginning of the list with a higher Z value than the others:
new_obj = Object()
new_obj.Z = 1000001

# Store the timing results in lists for performance testing:
results_native = []
bisect_results = []
sorted_container_results = []



print("START PERFORMANCE TEST")
# Run performance test multiple time:
for i in range(1000):
    print(i)

    #NATIVE

    # inserting new object at the beginning of the list:
    # current index:
    sorted_list = sorted(list_base, key=lambda name: name.Z)

    index = 0
    sorted_list.insert(index, new_obj)
    # Sort method native:
    start_time = time.time()
    sorted_list = sorted(sorted_list, key=lambda name: name.Z)
    finish_time_1 = time.time() - start_time
    results_native.append(finish_time_1)

    # BISECT:
    sorted_list_bisect = sorted(list_base, key=lambda name: name.Z)
    start_time = time.time()
    # insert the new value in the correct position
    bisect.insort(sorted_list_bisect, new_obj, key=lambda name: name.Z)
    finish_time = time.time() - start_time
    bisect_results.append(finish_time)

    # Making sure bisect gives the same answer as your native method.
    if not (np.array(sorted_list) == np.array(sorted_list_bisect)).all():
        print("Sorted lists do not match :(")
        raise Exception

    # SORTED CONTAINER:
    start_time = time.time()
    container_sorted_list.add(new_obj)
    finish_time = time.time() - start_time
    sorted_container_results.append(finish_time)
    container_sorted_list.remove(new_obj)

print("Native finish time:", mean(results_native))
print("Bisect finish time:", mean(bisect_results))
print("Sorted Container finish time:", mean(sorted_container_results))

Python相关问答推荐

通过优化空间在Python中的饼图中添加标签

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

Python中的嵌套Ruby哈希

scikit-learn导入无法导入名称METRIC_MAPPING64'

numpy卷积与有效

在含噪声的3D点网格中识别4连通点模式

未知依赖项pin—1阻止conda安装""

Python列表不会在条件while循环中正确随机化'

Polars asof在下一个可用日期加入

dask无groupby(ddf. agg([min,max])?''''

基于行条件计算(pandas)

python panda ExcelWriter切换动态公式到数组公式

在输入行运行时停止代码

在代码执行后关闭ChromeDriver窗口

PYTHON、VLC、RTSP.屏幕截图不起作用

当条件满足时停止ODE集成?

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

有没有办法在不先将文件写入内存的情况下做到这一点?

来自Airflow Connection的额外参数

递归链表反转与打印语句挂起