我有一个奇数和偶数相等数量的列表。目标是修改列表以在奇数索引处具有奇数整数,在偶数索引处具有甚至整数。
这是我的方法:
我找出偶数索引和奇数索引的数字。然后找出偶数索引处的奇数和奇数索引处的偶数。最后交换错位的数字。
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]
一样可能以相同的奇偶格式排序。
答案 0 :(得分:5)
创建列表的副本(仅用于创建等长的新列表),然后使用两个计数器来跟踪将偶数和奇数插入新列表的位置,将索引递增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]
答案 1 :(得分:2)
在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
答案 2 :(得分:1)
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]
答案 3 :(得分:1)
>>> 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]
答案 4 :(得分:0)
虽然你选择了答案,但我想提交自己的方式。希望你喜欢它。
# 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