为什么我不能在此函数中重新分配变量?
Why can't I reassign variables in this function?
这里是问题:
You will be given an array of numbers. You have to sort the odd numbers in ascending order while leaving the even numbers at their original positions.
这是我的代码:
def sort_array(source_array):
odd_ints = []
for i in source_array:
if i % 2 == 1:
odd_ints.append(i)
odd_ints.sort()
else:
pass
counter = 0
for x in source_array:
if x % 2 == 1:
x = odd_ints[counter]
counter += 1
print(source_array)
else:
pass
return source_array
当我测试它时,它是这样的:
>>> sort_array([5, 3, 2, 8, 1, 4])
[5, 3, 2, 8, 1, 4]
[5, 3, 2, 8, 1, 4]
[5, 3, 2, 8, 1, 4]
[5, 3, 2, 8, 1, 4]
由于某些原因,我无法将函数中的变量x
按升序重新赋值给odd_ints
。有人知道我的代码中的问题吗?
你只需要将奇数的位置也保存起来,就可以进行替换:
def sort_array(source_array):
odd_ints = []
positions = []
counter = 0 #need counter to get positions
for i in source_array:
if i % 2 == 1:
odd_ints.append(i) #keep the values
positions.append(counter) #keep the position
counter += 1
odd_ints.sort() #sort for replacement
counter2 = 0 #need second counter to place sorted list
for pos in positions:
source_array[pos] = odd_ints[counter2] #place the sorted values
counter2 += 1
return source_array
print(sort_array([5, 3, 2, 8, 1, 4]))
输出:
[1, 3, 2, 8, 5, 4]
你可以这样做:
- 将赔率与索引分离成字典;
- 对赔率进行排序并将索引重置为奇数槽;
- 将这些赔率插入原始列表。
示例:
def sort_the_odds(li):
odds={idx:n for idx,n in enumerate(li) if n%2}
for idx,val in zip([t[0] for t in sorted(odds.items())],
[t[1] for t in sorted(odds.items(), key=lambda t: t[1])]):
li[idx]=val
return li
>>> sort_the_odds([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
[10, 1, 8, 3, 6, 5, 4, 7, 2, 9]
>>> sort_the_odds([5, 3, 2, 8, 1, 4])
[1, 3, 2, 8, 5, 4]
修改了@eli-harold 的答案以使用更易读的语法:
def sort_array(source_array):
odd_ints = []
positions = []
for i, elem in enumerate(source_array):
if elem % 2:
odd_ints.append(elem) # keep the values
positions.append(i) # keep the position
odd_ints.sort() # sort for replacement
for pos, elem in zip(positions, odd_ints):
source_array[pos] = elem # place the sorted values
return source_array
print(sort_array([5, 3, 2, 8, 1, 4]))
或者,更简洁,
def sort_array(source_array):
positions, odd_ints = zip(*[(i, elem)
for i, elem in enumerate(source_array)
if elem % 2])
pos = iter(positions)
for elem in sorted(odd_ints):
source_array[next(pos)] = elem
return source_array
奖励:如果我们不应该就地排序(修改给定列表),以下方法将起作用:
def sort_array(arr):
odd_sorted_it = iter(sorted(el for el in arr if el % 2))
return [el if not el % 2 else next(odd_sorted_it) for el in arr]
这里是问题:
You will be given an array of numbers. You have to sort the odd numbers in ascending order while leaving the even numbers at their original positions.
这是我的代码:
def sort_array(source_array):
odd_ints = []
for i in source_array:
if i % 2 == 1:
odd_ints.append(i)
odd_ints.sort()
else:
pass
counter = 0
for x in source_array:
if x % 2 == 1:
x = odd_ints[counter]
counter += 1
print(source_array)
else:
pass
return source_array
当我测试它时,它是这样的:
>>> sort_array([5, 3, 2, 8, 1, 4])
[5, 3, 2, 8, 1, 4]
[5, 3, 2, 8, 1, 4]
[5, 3, 2, 8, 1, 4]
[5, 3, 2, 8, 1, 4]
由于某些原因,我无法将函数中的变量x
按升序重新赋值给odd_ints
。有人知道我的代码中的问题吗?
你只需要将奇数的位置也保存起来,就可以进行替换:
def sort_array(source_array):
odd_ints = []
positions = []
counter = 0 #need counter to get positions
for i in source_array:
if i % 2 == 1:
odd_ints.append(i) #keep the values
positions.append(counter) #keep the position
counter += 1
odd_ints.sort() #sort for replacement
counter2 = 0 #need second counter to place sorted list
for pos in positions:
source_array[pos] = odd_ints[counter2] #place the sorted values
counter2 += 1
return source_array
print(sort_array([5, 3, 2, 8, 1, 4]))
输出:
[1, 3, 2, 8, 5, 4]
你可以这样做:
- 将赔率与索引分离成字典;
- 对赔率进行排序并将索引重置为奇数槽;
- 将这些赔率插入原始列表。
示例:
def sort_the_odds(li):
odds={idx:n for idx,n in enumerate(li) if n%2}
for idx,val in zip([t[0] for t in sorted(odds.items())],
[t[1] for t in sorted(odds.items(), key=lambda t: t[1])]):
li[idx]=val
return li
>>> sort_the_odds([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
[10, 1, 8, 3, 6, 5, 4, 7, 2, 9]
>>> sort_the_odds([5, 3, 2, 8, 1, 4])
[1, 3, 2, 8, 5, 4]
修改了@eli-harold 的答案以使用更易读的语法:
def sort_array(source_array):
odd_ints = []
positions = []
for i, elem in enumerate(source_array):
if elem % 2:
odd_ints.append(elem) # keep the values
positions.append(i) # keep the position
odd_ints.sort() # sort for replacement
for pos, elem in zip(positions, odd_ints):
source_array[pos] = elem # place the sorted values
return source_array
print(sort_array([5, 3, 2, 8, 1, 4]))
或者,更简洁,
def sort_array(source_array):
positions, odd_ints = zip(*[(i, elem)
for i, elem in enumerate(source_array)
if elem % 2])
pos = iter(positions)
for elem in sorted(odd_ints):
source_array[next(pos)] = elem
return source_array
奖励:如果我们不应该就地排序(修改给定列表),以下方法将起作用:
def sort_array(arr):
odd_sorted_it = iter(sorted(el for el in arr if el % 2))
return [el if not el % 2 else next(odd_sorted_it) for el in arr]