Python:排序数组的交替元素

时间:2013-07-02 22:29:34

标签: python

在我的小项目中,我按降序对列表进行了排序,但是,我的目标是在此自定义模式中对其进行排序。 (最大 - >最小 - >下一个最大 - >下一个最小 - >)等。

在java中,我能够这样做:

public static void wackySort(int[] nums) {
    //first, this simply sorts the array by ascending order.
    int sign = 0;
    int temp = 0;
    int temp2 = 0;
    for (int i = 0; i < nums.length; i++) {
        for (int j = 0; j < nums.length -1; j++){
            if (nums[j] > nums[j+1]) {
               temp = nums[j];
               nums[j] = nums[j+1];
               nums[j+1] = temp;
            }
        }
    }

    //prepare for new array to actually do the wacky sort.
    System.out.println();
    int firstPointer = 0;
    int secondPointer = nums.length -1;
    int[] newarray = new int[nums.length];
    int size = nums.length;

    //increment by two taking second slot replacing the last (n-1) term
    for (int i = 0; i < nums.length -1; i+=2) {
        newarray[i] = nums[firstPointer++];
        newarray[i+1] = nums[secondPointer--];
    }

    //store those values back in the nums array    
    for (int i = 0; i < nums.length; i++) {
        nums[i] = newarray[i];
    }
}

我的目标是在python中做同样的事情,除了向后。关于如何将最后一个转换为循环的任何想法,将wackysort转换为python并使其向后移动?

5 个答案:

答案 0 :(得分:5)

我建议先正常排序,然后再进行洗牌:

inlist=[3,5,7,6,9,8,2,1]
inlist.sort()
outlist=[]
while len(inlist)>0:
  if (len(outlist)%2==0):
      outlist.append(inlist.pop())
  else:
      outlist.append(inlist.pop(0))

答案 1 :(得分:5)

nums = [1, 2, 3, 4]
newarray = sum(zip(reversed(nums), nums), ())[:len(nums)]

>>> print(newarray)
(4, 1, 3, 2)

它的作用,一步一步。首先,reversed()

>>> list(reversed(nums))
[4, 3, 2, 1]

然后zip()

>>> list(zip([4, 3, 2, 1], [1, 2, 3, 4]))
[(4, 1), (3, 2), (2, 3), (1, 4)]

你可以看到我们几乎有我们想要的列表,我们有一个问题:这些是元组。我们想要压扁它们。

>>> (4, 1) + (3, 2) + (2, 3) + (1, 4)
(4, 1, 3, 2, 2, 3, 1, 4)

喔。真好。但如何在列表中做到这一点?简单:使用sum(),这正是这一点 - 将许多东西放在一起。只有我们需要先给它一些东西 - 空元组()

>>> sum([(4, 1), (3, 2), (2, 3), (1, 4)], ())
(4, 1, 3, 2, 2, 3, 1, 4)

但是我们不想要下半场,所以让我们删除它。我们知道他的名单已经两次太长了,是吗?

>>> (4, 1, 3, 2, 2, 3, 1, 4)[:len(nums)]
(4, 1, 3, 2)

就是这样。


另一种选择:

from itertools import chain, islice
a = list(islice(chain.from_iterable(zip(nums, reversed(nums))), len(nums)))

答案 2 :(得分:0)

最后一个循环:

for (int i = 0; i < nums.length; i++){
    nums[i] = newarray[i];

...是Python中的一个单行程序。确切的等价物是:

nums[:] = newarray[:len(nums)]

然而,最有可能的是,你真正需要的是:

nums = newarray

如果你真的想出于某种原因想用“Java风格”来写它,那就是:

i = 0
while i < len(nums):
    nums[i] = newarray[i]
    i += 1

但这与第一个版本完全相同,只是速度越慢越慢,也越不可读。


同时,对于上一个循环:

for (int i = 0; i < nums.length -1; i+=2){
    newarray[i] = nums[firstPointer++];
                newarray[i+1] = nums[secondPointer--];

同样,您可以将此或多或少地直接翻译为Python:

i = 0
while i < len(nums)-1:
    newarray[i] = nums[firstPointer]
    firstPointer += 1
    newarray[i+1] = nums[secondPointer]
    secondPointer -= 1
    i += 2

但是与上一个循环的最后一个版本一样,这是非常难以理解的,如果你试着描述算法,那么你会更开心,然后用Python写出来。

答案 3 :(得分:0)

正如我在上一个问题的评论中所说,做你想做的最简单的方法就是首先编写一个可以将已经排序的列表交换到你想要的顺序的函数,然后就可以了你的排序功能和新功能一起。

def wacky_sort(seq):
    # code you already have

def alternate_ends(seq):
    new_seq = []
    while seq:
        new_seq.append(seq.pop(0))
        if seq:
            new_seq.append(seq.pop())
    return new_seq

def wacky_sort_with_alternating_ends(seq):
    wacky_sort(seq)
    return alternate_ends(seq)

答案 4 :(得分:0)

如果您想在O(1)额外空间和O(n)时间中解决此问题,则可以像下面的代码一样解决。

def重新排列(arr,n):

k,j=1,1
a=[0]*n
for i in range(0,n):

    if i%2==0:
        a[i]=arr[n-k]
        k=k+1

    else:
        a[i]=arr[i-j]
        j=j+1
for i in range(n):
    arr[i]=a[i]