[英]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.