移动列表的最后一个元素

时间:2015-01-28 14:48:54

标签: python arrays algorithm sorting array-algorithms

我正在寻找将python中列表的最后一个元素移动到适当位置的有效方法。例如,如果我们有list = [1,3,4,5,6,2],我们应该得到list = [1,2,3,4,5,6]。我尝试过的方法并不理想:

    def sort1(lng, lst):
        if len(lst) != lng:
            return
        else:
            i = -2
            last = lst[-1]
            for x in lst:
                if last < lst[i]:
                    lst[i] = last
                    i -= 1
                    print(lst)
    sort1(6,[1,3,4,5,6,2])


It is giving me following result:
   [1, 3, 4, 5, 2, 2]
   [1, 3, 4, 2, 2, 2]
   [1, 3, 2, 2, 2, 2]
   [1, 2, 2, 2, 2, 2]

4 个答案:

答案 0 :(得分:6)

从列表中弹出项目并使用bisect.insort_left将其插回:

>>> import bisect
>>> lst = [1, 3, 4, 5, 6, 2]
>>> item = lst.pop()
>>> bisect.insort_left(lst, item)
>>> lst
[1, 2, 3, 4, 5, 6]

答案 1 :(得分:1)

适当的方法是插入排序算法,但现在我们只对最后一项进行,所以这里是:

list = [1, 3, 4, 5, 6, 2] # our list
item = list[len(list)-1] # last element
i = len(list)-2 # the starting element to compare the last element to
while item<list[i] and i>=0: # while place not found and index in range
    list[i+1]=list[i] # move element at i to i+1
    i-=1 # decrement i, so to compare with next left element
list[i+1]=item # when the loop is completed, we then have our last item's position in i+1
print(list) # this prints [1, 2, 3, 4, 5, 6]


你可以阅读更多关于插入排序算法的内容,这里解释起来有点棘手,我的意思是需要一个很长的解释和例子,所以,你可以在维基百科上看到更多:https://en.wikipedia.org/wiki/Insertion_sort

答案 2 :(得分:0)

不像@Ashwini的回答那么性感,但你可以尝试一下。

而不是:

    lst[i] = last

(当你向下移动时,用你的最后一个值覆盖你的整个数组)

这样做:

    lst[i+1] = lst[i]

(这会将所有值都移过)

然后在所有循环之后:

    lst[i+1] = last

(将最后一个值放在正确的位置,这是i + 1的位置)

答案 3 :(得分:0)

如果你必须编写自己的函数,你可以使用枚举,找到ele落在两个值之间的位置,或者小于或等于第一个值:

def sor1(lst):
    # empty or list with single ele or  last ele is larger than second last the list os sorted
    if len(lst) < 2 or lst[-1] > lst[-2]:
        return lst
    last = lst.pop()
    # if first value is larger than the last we need to insert last before the first
    if lst[0] >= last:
        lst.insert(0, last)
        return lst
    # else find first place where last falls between two values
    for ind, ele in enumerate(lst):
        if ele <= last <= lst[ind+1]:
            lst.insert(ind+1,last)
            return lst

还有一个blist库,其中插入是0(log n),并且它优于其他一些python列表操作,在某些情况下,反向也是如此,因此它将取决于您想要做的事情:

from blist import blist
lst =  blist([1, 3, 4, 5, 6, 2])

blist比列表更有效的一些操作:

  • 插入或删除清单O(log n)O(n)

  • 插入或删除清单O(log n)O(n)

  • 拍摄清单O(log n)O(n)

  • 制作列表的浅表副本O(1)O(n)

  • 更改列表切片O(log n + log k)O(n + k)

  • 将列表相乘以制作稀疏列表O(log k)O(kn)

  • 使用bisect.insort维护已排序的列表O(log ** 2 n)O(n)

使用python 2.7:

使用insort_left稍微优于列表
In [32]: %%timeit
lst = list(range(1000000))+[90000]
item = lst.pop()
bisect.insort_left(lst, item)
   ....: 
10 loops, best of 3: 38.5 ms per loop

In [33]: %%timeit
lst = blist(range(1000000))+blist([90000])
item = lst.pop()
bisect.insort_left(lst, item)
   ....: 
10 loops, best of 3: 27.9 ms per loop