python 3:列表的值在进入for循环时发生变化

时间:2018-12-29 07:23:55

标签: python arrays sorting

挑战:从包含5个元素的列表中从四个元素中找出最小和最大和。

方法:按照降序和升序对列表进行排序,并将它们存储在两个不同的变量中。在两个列表中找到前4个元素的总和。一个总和为最小,第二个为最大。

代码:

arr = [2,1,3,4,5]
arr.sort()
asc = arr
print(asc[0],asc[1],asc[2],asc[3])
arr.sort(reverse = True)
des = arr
print(des[0],des[1],des[2],des[3])
maxi = 0
mini = 0
for j in range(4) :
    mini = mini + asc[j]
    print(mini, asc[j])
    maxi = maxi + des[j]
    print(maxi,des[j])
print(mini, maxi)

此处出于调试目的引入了一些打印语句。从代码中可以看出,bot将在进入for循环之前和进入循环之后打印已排序的版本。从输出中可以清楚地看到,应该按升序保存元素的列表按降序排列元素。

输出:

11 12 13 14 - list in the ascending order
15 14 13 12 - list in the descending order

15 15 - round 0
15 15

29 14 - round 1
29 14

42 13 - round 2
42 13

54 12 - round 3
54 12

54 54 - final output

为什么一个特定列表中的元素进入for循环时会改变顺序?

2 个答案:

答案 0 :(得分:5)

在执行asc = arrdes = arr时,不会创建新列表。 ascdesarr链接到一个列表对象,因此,乳清您更改其中的任何一个,所有变量都将更改为单个对象。

In [1]: a = [1, 2]

In [2]: b = a

In [3]: id(a), id(b)
Out[3]: (140601802913048, 140601802913048)

In [4]: b = a[:]

In [5]: id(a), id(b)
Out[5]: (140601802913048, 140601819243872)

如果您想获得列表的副本,请

asc = arr[:]
des = arr[:]

答案 1 :(得分:2)

您需要这样做:

asc = arr.copy()
# or asc = arr[:]

否则,当arr被反向排序时,asc也将改变。 asc是指向数组的指针,当arr更改时,asc也会更改。更好的是,您创建了arr的副本,因此更改不会反映回来。


您编写的整个代码可以归纳为以下两行:

arr = [2,1,3,4,5]

print(sum(sorted(arr)[:4]))  # 10
print(sum(sorted(arr, reverse=True)[:4]))  # 14

# Or print(sum(sorted(arr)[-4:])) instead of the last print.