将项目插入Python中的排序列表


74

我正在创建一个类,其中的一种方法将新项目插入已排序列表中。该项目将插入到已排序列表中的更正(已排序)位置。我不能使用任何内置列表功能或其它方法相比[][:]+,和len虽然。这部分确实让我感到困惑。

最好的方法是什么?


10
家庭作业?您可能会首先在网上搜索如何将元素插入到已排序列表中。
菲利克斯·克林

3
我不允许使用和内置列表功能
Will S

1
@FelixKling OP表示,不允许.insert()使用OP会使它感到困惑。对于在特定情况下找到任何人对此有很好关注的大量搜索,并不是很期望。
n611x007

Answers:


122

使用bisect模块的分类功能:

import bisect 
a = [1, 2, 4, 5] 
bisect.insort(a, 3) 
print(a)

输出量

[1, 2, 3, 4, 5] 

6
当项目不是整数时,缺少该怎么办。即我该如何在现实世界中使用它?
Velda

2
@Velda,这是一个非整数的示例:s = ['a', 'b', 'd']; bisect.insort(s, 'c'); assert(s == ['a', 'b', 'c', 'd'])
Joseph Holsten

8
仍然是整数示例。顺便说一句,您多久对一次信件进行排序...?如果我想按某个类的某个属性对某个类的实例进行排序怎么办?
Velda

2
@Velda如果要比较自定义类,则可以实现__lt__方法,并且bisect.insort能够正确地对类实例进行排序。docs.python.org/3/library/operator.html#operator.__lt__
真实的

2
这在O(n)中运行。从算法上来说,这并不比简单地扫描列表,找到合适的位置并重新排列列表中的元素以维持排序的顺序
更好

78

提示1:您可能想在bisect模块中研究Python代码。

提示2: 切片可用于列表插入:

>>> s = ['a', 'b', 'd', 'e']
>>> s[2:2] = ['c']
>>> s
['a', 'b', 'c', 'd', 'e']

由于不允许OP使用任何函数或方法,因此保留切片是将新元素插入列表的唯一方法。
Raymond Hettinger

4
bisect非常适合排序列表的插入,但是由于使用python的基本列表,因此速度下降到O(N)。市场上有链表之类的东西吗?
Maksim Gayduk '16

@MaksimGayduk在pypi.python.org/pypi/blist/1.3.6尝试blist模块。也就是说,此职位的OP在允许使用哪些工具方面有一些相当严格的限制。
Raymond Hettinger

36

您应该使用bisect模块。另外,在使用bisect.insort_left之前,需要对列表进行排序

这是一个很大的差异。

>>> l = [0, 2, 4, 5, 9]
>>> bisect.insort_left(l,8)
>>> l
[0, 2, 4, 5, 8, 9]

timeit.timeit("l.append(8); l = sorted(l)",setup="l = [4,2,0,9,5]; import bisect; l = sorted(l)",number=10000)
    1.2235019207000732

timeit.timeit("bisect.insort_left(l,8)",setup="l = [4,2,0,9,5]; import bisect; l=sorted(l)",number=10000)
    0.041441917419433594

3

我现在正在学习算法,所以我想知道等分模块是如何编写的。这是bisect模块中的有关将项目插入已排序列表的代码,该代码使用二分法:

def insort_right(a, x, lo=0, hi=None):
    """Insert item x in list a, and keep it sorted assuming a is sorted.
    If x is already in a, insert it to the right of the rightmost x.
    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if x < a[mid]:
            hi = mid
        else:
            lo = mid+1
    a.insert(lo, x)

1

这是您可能的解决方案:

a = [15, 12, 10]
b = sorted(a)
print b # --> b = [10, 12, 15]
c = 13
for i in range(len(b)):
    if b[i] > c:
        break
d = b[:i] + [c] + b[i:]
print d # --> d = [10, 12, 13, 15]

8
这不是最佳解决方案,该bisect模块将在O(log n)步骤中找到插入点,您可能必须搜索整个列表,即O(n)复杂度。
马丁·彼得斯

0
# function to insert a number in an sorted list


def pstatement(value_returned):
    return print('new sorted list =', value_returned)


def insert(input, n):
    print('input list = ', input)
    print('number to insert = ', n)
    print('range to iterate is =', len(input))

    first = input[0]
    print('first element =', first)
    last = input[-1]
    print('last element =', last)

    if first > n:
        list = [n] + input[:]
        return pstatement(list)
    elif last < n:
        list = input[:] + [n]
        return pstatement(list)
    else:
        for i in range(len(input)):
            if input[i] > n:
                break
    list = input[:i] + [n] + input[i:]
    return pstatement(list)

# Input values
listq = [2, 4, 5]
n = 1

insert(listq, n)

-9

这是追加列表并将值插入已排序列表的最佳方法:

 a = [] num = int(input('How many numbers: ')) for n in range(num):
     numbers = int(input('Enter values:'))
     a.append(numbers)

 b = sorted(a) print(b) c = int(input("enter value:")) for i in
 range(len(b)):
     if b[i] > c:
         index = i
         break d = b[:i] + [c] + b[i:] print(d)`
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.