只要列表没有排序,就继续用迭代器与其自身合并来替换它.这是(相当于)一种常见的排序算法,只是奇怪地实现了,还是有什么新东西?

from random import shuffle
from heapq import merge
from itertools import pairwise

# Create test data
a = list(range(100))
shuffle(a)

# Sort
while any(x > y for x, y in pairwise(a)):
    it = iter(a)
    a = list(merge(it, it))

print(a)

Attempt This Online!

heapq.merge确实以"标准"的方式合并了两个输入,但这是一个实现细节,它的输入应该是排序的,但它们不在这里(它们也不是独立的,因为它们使用相同的源).为了消除它作为一个实现细节,让merge实际上是这样(标准方法,总是比较两个"当前"值,得到较小的一个并获取它的替代):

def merge(xs, ys):
    none = object()
    x = next(xs, none)
    y = next(ys, none)
    while (x is not none) and (y is not none):
        if x <= y:
            yield x
            x = next(xs, none)
        else:
            yield y
            y = next(ys, none)
    if x is not none:
        yield x
    if y is not none:
        yield y
    yield from xs
    yield from ys

推荐答案

它确实是实现得很奇怪的冒泡排序.

冒泡排序重复执行此操作,直到对列表进行排序:

  • 在列表上滑动一个包含两个项目的窗口.在每个位置,对窗口中的两个项目进行排序,然后将窗口向右滑动一个位置.这会将较小的项留在后面,较大的项保留在窗口中,而下一项进入窗口.

具有相同迭代器两次的merge实际上做了同样的事情.它的"两项窗口"是两个"当前值",即问题merge实现中的xy.与冒泡排序中一样,较小的项被"落在后面"(被生成,成为输出中的下一项).较大的保留在"窗口"中(保留xy).并且来自输入列表的下一项进入窗口(变成xy中的另一个).

想想Knuth的"100",让我们也试一试,通过实验判断它的行为是否真的与普通的气泡排序相同.用我的问题排序和冒泡排序对一个有Beware ... I have only proved it ... not tried it0个元素的混洗列表进行排序,并在每一轮之后记录列表的状态.它们在这两种类型中都是相同的.

from random import shuffle
from heapq import merge
from itertools import pairwise

# Create test data
a = list(range(1000))
shuffle(a)

def mysort_steps(a):
    steps = []
    while any(x > y for x, y in pairwise(a)):
        it = iter(a)
        a = list(merge(it, it))
        steps.append(a[:])
    return steps

def bubblesort_steps(a):
    steps = []
    n = len(a)
    for i in range(n - 1):
        swapped = False
        for j in range(n - 1 - i):
            if a[j] > a[j+1]:
                a[j], a[j+1] = a[j+1], a[j]
                swapped = True
        if not swapped:
            break
        steps.append(a[:])
    return steps

print(mysort_steps(a[:]) == bubblesort_steps(a[:]))

Attempt This Online!

Python相关问答推荐

Python在tuple上操作不会通过整个单词匹配

需要计算60,000个坐标之间的距离

对于一个给定的数字,找出一个整数的最小和最大可能的和

如何在polars(pythonapi)中解构嵌套 struct ?

Mistral模型为不同的输入文本生成相同的嵌入

使用setuptools pyproject.toml和自定义目录树构建PyPi包

如何创建一个缓冲区周围的一行与manim?

如何让这个星型模式在Python中只使用一个for循环?

ThreadPoolExecutor和单个线程的超时

迭代嵌套字典的值

考虑到同一天和前2天的前2个数值,如何估算电力时间序列数据中的缺失值?

通过ManyToMany字段与Through在Django Admin中过滤

在Python中使用yaml渲染(多行字符串)

为用户输入的整数查找根/幂整数对的Python练习

如何将相同组的值添加到嵌套的Pandas Maprame的倒数第二个索引级别

Python如何导入类的实例

将像素信息写入文件并读取该文件

VSCode Pylance假阳性(?)对ImportError的react

使用Scikit的ValueError-了解

按最大属性值Django对对象进行排序