Zci*_*rus 7 python sorting list python-3.x
我有一个包含约 50k 个自定义数据类型元素的列表(后者对我的问题可能并不重要)我正在使用 python 内置list.sort()
方法对列表进行排序。
myList: List[Foo] = ...
myList.sort(key=Foo.x)
Run Code Online (Sandbox Code Playgroud)
由于排序需要几分钟,我希望排序过程有一个进度条。我在网上没有找到任何解决方案。
这可能吗?我知道排序算法可能很复杂,并且可能根本无法测量排序进度。然而,对于我的用例来说,有一个“粗略”的测量就可以了,比如 25%、50%、75%……
fla*_*kes 14
鉴于 提供的接口sort
,您没有太多选项来挂钩实际的排序算法。但是,如果 50K 个键很慢,则很可能是调用该key
函数很慢,这是在实际排序之前计算的。
来自文档:
\n\n\n列表中每一项对应的键都会计算一次,然后用于整个排序过程。
\n
因此,如果您计算该方法被调用的次数key
,您就可以获得整个排序过程的粗略估计。为此,您可以为该key
函数创建一个包装器来管理簿记:
def progress_sort(data, *, key=lambda v: v, on_increment=None):\n total = len(data)\n\n if on_increment is None:\n start = time.time()\n\n def on_increment(c):\n print(f"{time.time() - start}: {c/total * 100}%")\n\n count = 0\n\n def progress_key(val):\n nonlocal count\n if count % int(total / 10) == 0:\n on_increment(count)\n count += 1\n return key(val)\n\n data.sort(key=progress_key)\n on_increment(total)\n
Run Code Online (Sandbox Code Playgroud)\n带有一些虚拟数据和慢速关键方法的示例
\ndef slow_key(val):\n time.sleep(1.0/500_000)\n return val\n\ndata = [random.randint(-50_000, 50_000)/1.0 for i in range(50_000)]\nprogress_sort(data, key=slow_key)\n
Run Code Online (Sandbox Code Playgroud)\n0.0: 0.0%\n0.5136210918426514: 10.0%\n1.0435900688171387: 20.0%\n1.6074442863464355: 30.0%\n2.156496524810791: 40.0%\n2.9734878540039062: 50.0%\n3.4794368743896484: 60.0%\n4.016523599624634: 70.0%\n4.558118104934692: 80.0%\n5.047779083251953: 90.0%\n5.545809030532837: 100.0%\n
Run Code Online (Sandbox Code Playgroud)\n然后可以将此方法与您希望用于更新状态的任何类型的库结合起来。您可能希望进一步配置提供给所提供的挂钩的数据,但是原理保持不变。
\n这是一个使用的示例tqdm
:
def slow_key(val):\n time.sleep(1.0/500_000)\n return val\n\n\ndata = [random.randint(-50_000, 50_000)/1.0 for i in range(50_001)]\n\nwith tqdm(total=len(data), desc="sorting") as pbar:\n progress_sort(data, key=slow_key, on_increment=lambda c: pbar.update(c - pbar.n))\n pbar.set_description("Finished")\n
Run Code Online (Sandbox Code Playgroud)\nsorting: 80%|\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x89 | 40000/50001 [00:05<00:01, 5802.30it/s]\n
Run Code Online (Sandbox Code Playgroud)\nFinished: 100%|\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88| 50001/50001 [00:07<00:00, 6489.14it/s]\n
Run Code Online (Sandbox Code Playgroud)\n