1

我正在寻找将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

4 回答 4

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]
于 2015-01-28T14:51:53.173 回答
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]

您可以在此处阅读有关插入排序算法的更多信息。

于 2016-05-02T23:46:11.080 回答
0

不像@Ashwini 的回答那么性感,但你可以试试这个。

代替:

    lst[i] = last

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

做这个:

    lst[i+1] = lst[i]

(这会将所有值转移过来)

然后在所有循环之后:

    lst[i+1] = last

(将最后一个值放在正确的位置,即 i+1 应该在的位置)

于 2015-01-28T14:59:48.130 回答
0

如果您必须编写自己的函数,您可以使用 enumerate 并找到 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
于 2015-01-28T15:00:58.700 回答