2

ここでの私の小さなプロジェクトでは、リストを降順で並べ替えましたが、私の目標は、このカスタム パターンで並べ替えることです。(最大 -> 最小 -> 次に大きい -> 次に小さい ->) など。

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で行うことです。奇抜な並べ替えを行う最後の for ループを python に変換し、逆方向にする方法についてのアイデアはありますか?

4

5 に答える 5

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

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

それが何をするか、一歩一歩。まず、逆() :

>>> 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)

でも後半は要らないので削除しましょう。彼のリストが正確に 2 倍長すぎることはわかっていますよね?

>>> (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)))
于 2013-07-02T22:42:46.770 に答える
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))
于 2013-07-02T22:36:28.127 に答える
0

最後の for ループ:

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 で記述しようとすると、非常に満足できるでしょう。

于 2013-07-02T22:35:40.410 に答える
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)
于 2013-07-02T22:41:43.417 に答える