簡體   English   中英

將列表中的奇數和偶數移動到奇數和偶數位置

[英]Move odd and even numbers in list to odd and even positions

我有一個列表,其中包含相等數量的奇數和偶數。 目標是修改列表以在奇數索引處具有奇數整數,在偶數索引處具有偶數整數。

這是我的方法:

我找出偶數索引和奇數索引處的數字。 然后找出偶數索引處的奇數和奇數索引處的偶數。 最后交換錯位的數字。

x = [3, 2, 5, 6, 4, 7, 8, 9, 10, 11]
even_pos = []
odd_pos = []
for i in range(len(x)):
    if x[i] % 2 == 0:
        even_pos.append(i)
    else:
        odd_pos.append(i)

even_pos_with_odd = []
odd_pos_with_even = []

for j in range(len(even_pos)):
    if even_pos[j] % 2 != 0:
        even_pos_with_odd.append(j)
    if odd_pos[j] % 2 == 0:
        odd_pos_with_even.append(j)

for n in range(len(even_pos_with_odd)):
    temp =  x[odd_pos[odd_pos_with_even[n]]]
    x[odd_pos[odd_pos_with_even[n]]] = x[even_pos[even_pos_with_odd[n]]]
    x[even_pos[even_pos_with_odd[n]]] = temp

雖然它有效,但我對解決方案不是很滿意。 有沒有更有效的解決方案來解決我的問題? 我的目標是使x[][2, 3, 6, 5, 4, 7, 8, 9, 10, 11]一樣可能以相同的奇偶格式排序。

創建列表的副本(僅用於創建等長的新列表),然后使用兩個計數器跟蹤將偶數和奇數插入新列表的位置,每次將索引增加 2:

def odd_even_sieve(x):
    output = x[:]
    even_index, odd_index = 0, 1
    for value in x:
        if value % 2 == 0:
            output[even_index] = value
            even_index += 2
        else:
            output[odd_index] = value
            odd_index += 2
    return output

這比嘗試就地交換所有內容要簡單得多。

演示:

>>> def odd_even_sieve(x):
...     output = x[:]
...     even_index, odd_index = 0, 1
...     for value in x:
...         if value % 2 == 0:
...             output[even_index] = value
...             even_index += 2
...         else:
...             output[odd_index] = value
...             odd_index += 2
...     return output
... 
>>> odd_even_sieve([3, 2, 5, 6, 4, 7, 8, 9, 10, 11])
[2, 3, 6, 5, 4, 7, 8, 9, 10, 11]
>>> odd_even_sieve([19, 11, 23, 16, 18, 20])
[16, 19, 18, 11, 20, 23]

對於排序輸出(奇數和偶數獨立排序),只需對輸入進行排序:

>>> odd_even_sieve(sorted([3, 2, 5, 6, 4, 7, 8, 9, 10, 11]))
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> odd_even_sieve(sorted([19, 11, 23, 16, 18, 20]))
[16, 11, 18, 19, 20, 23]

O(n**2)時間內將所有偶數項移動到偶數索引並將所有奇數項移動到奇數索引:

def fix_odd_even_indices(lst):
    for i in range(len(lst)):
        j = i
        while i & 1 != lst[i] & 1: # element is in the wrong place
            j += 1
            lst[i], lst[j] = lst[j], lst[i] # swap

如果奇數和偶數不相等,代碼可能會引發IndexError

例子:

lst = [3, 2, 5, 6, 4, 7, 8, 9, 10, 11]
fix_odd_even_indices(lst)
print(lst)
# -> [2, 3, 6, 5, 4, 7, 8, 9, 10, 11]

這是一個返回副本的線性解決方案:

def fixed_odd_even_indices(seq):
    L = [None]*len(seq)
    L[1::2] = [x for x in seq if x & 1] # odd
    L[::2] = [x for x in seq if not x & 1] # even
    return L

例子:

print(fixed_odd_even_indices([3, 2, 5, 6, 4, 7, 8, 9, 10, 11]))
# -> [2, 3, 6, 5, 4, 7, 8, 9, 10, 11]

這是一個返回副本的線性單遍解決方案(它可能比以前的解決方案慢):

def fixed_odd_even_indices(iterable):
    odds, evens = [], []
    for x in iterable:
        (odds if x & 1 else evens).append(x)
    return [x for pair in zip(evens, odds) for x in pair]

例子:

L = fixed_odd_even_indices(map(int, sys.stdin)) # input one integer per line
def odd_even(x):
    odds = sorted(filter(lambda n: n % 2 == 1, x))
    evens = sorted(filter(lambda n: n % 2 == 0, x))
    pairList = zip(odds, evens)
    return [n for t in pairList for n in t]

@MartijnPieters 解決方案的itertools.count版本

>>> from itertools import count
>>> x = [3, 2, 5, 6, 4, 7, 8, 9, 10, 11]
>>> def odd_even_sieve(x):
        output = x[:]
        a, b = count(0, 2), count(1, 2)
        for value in x:
            output[next(a if value % 2 == 0 else b)] = value
        return output

>>> odd_even_sieve(x)
[2, 3, 6, 5, 4, 7, 8, 9, 10, 11]

雖然你選擇了你的答案,但我想提交我的方式。 希望你會喜歡。

# Using python  2.7

First_list = [1,3,5,7,2,4,6,8]   #equal no. of even and odd numbers

temp_odd = [x for x in First_list if x%2 ==1]
temp_even = [x for x in First_list if x%2 ==0]

First_list[0::2] = temp_even    # as we know,0 is even index,followed by 2,4...
First_list[1::2] = temp_odd     # similarly starting with index 1, odd indices 
                                # are 3,5 ...
                                # we can write sorted(temp_odd) like that

print First_list

如果有人正在尋找 function 來翻轉數組的奇數和偶數索引,他/她可以使用這個:

import numpy as np
def flip(x):
        '''x must be an array'''
        flipped=[]
        for i in range(int(len(x)/2)):
                flipped.append(x[(i+1)*2-1])
                flipped.append(x[i*2])
        flipped=np.array(flipped)
        return flipped
>>> print(x)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
>>> print(flip(x))
[ 1  0  3  2  5  4  7  6  9  8 11 10 13 12 15 14 17 16 19 18]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM