为什么这个简单的Python程序没有给出正确的输出?

amrnrhlw  于 2023-03-09  发布在  Python
关注(0)|答案(4)|浏览(137)

挑战如下:
你将得到一个数字数组,你必须将奇数按升序排序,而将偶数保留在原来的位置。

[7, 1]  =>  [1, 7]
[5, 8, 6, 3, 4]  =>  [3, 8, 6, 5, 4]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]  =>  [1, 8, 3, 6, 5, 4, 7, 2, 9, 0]

我的代码逻辑是:该函数接受一个源数组(src_arr),我创建了一个仅包含奇数的新数组,并在odd_arr中对它们进行排序,在for循环中,if语句检查src_arr中的每个数字是否为奇数,并将其替换为odd_arr中对应的排序后的奇数。

def sort_array(src_arr):
    odd_arr = sorted([num for num in src_arr if num%2 != 0])
    i = 0
    for num in src_arr:
        if num%2 != 0:
            src_arr[src_arr.index(num)] = odd_arr[i]
            i += 1
    return src_arr

print(sort_array([5, 3, 2, 8, 1, 4]))

输入是[5, 3, 2, 8, 1, 4],输出应该是[1, 3, 2, 8, 5, 4],但是我一直得到与输入完全相同的输出,我做了一个pdb.trace(),一切正常,直到输入列表中的数字1,我不明白为什么它没有给出正确的输出。

icomxhvb

icomxhvb1#

通过将odd_arr设为奇数排序列表上的迭代器,并在需要时调用next(odd_arr),甚至可以稍微简化代码,而无需手动管理索引:

def sort_array(src_arr):
    odd_arr = iter(sorted([num for num in src_arr if num%2 != 0]))
    for idx, num in enumerate(src_arr):
        if num%2 != 0:
            src_arr[idx] = next(odd_arr)
    return src_arr

print(sort_array([5, 3, 2, 8, 1, 4]))

# [1, 3, 2, 8, 5, 4]
gdx19jrr

gdx19jrr2#

您选择在src_arr上运行for-循环,并在odd_arr上维护手动索引i
就我个人而言,我发现在odd_arr上运行for-loop并在src_arr上维护手动索引i要简单得多。
这是因为我们希望按顺序查看odd_arr的每个元素,所以一个简单明了的for-循环是合适的;但是src_arr是我们要跳过元素的数组,所以维护我们自己的索引i并跳过我们想手动跳过的元素更容易。

def sort_array(src_arr):
    odd_arr = sorted(num for num in src_arr if num % 2 != 0)
    i = 0
    for x in odd_arr:
        while src_arr[i] % 2 == 0:    # skip even numbers in src_arr
            i += 1
        src_arr[i] = x
        i += 1
    return src_arr

print(sort_array([5, 3, 2, 8, 1, 4]))
# [1, 3, 2, 8, 5, 4]
hc8w905p

hc8w905p3#

另一种查看方法是更改原始数组,因此在用1替换5后,数字1有两个索引
只要您有一个拷贝,并在保持原始阵列完整的同时更改拷贝,就可以解决问题

def sort_array(src_arr):
    odd_arr = sorted([num for num in src_arr if num%2 != 0])
    new_arr = src_arr[:]
    i = 0
    for num in src_arr:
        if num%2 != 0:
            new_arr[src_arr.index(num)] = odd_arr[i]
            i += 1
    return new_arr

print(sort_array([5, 3, 2, 8, 1, 4]))
z6psavjg

z6psavjg4#

已经有一些很棒的答案贴出来了。这里还有一个选择--为了好玩。它的灵感也来自于之前的评论。

def sort_odd(A):
    # generator expression to extract odd numbers first
    odds = sorted(x for x in A if x & 1)[::-1] 

    # List Comp to achieve:
    # replace odd num. one by one, leave evens unchanged
    return [x if not x&1 else odds.pop() for x in A]

print(sort_odd(L))

相关问题