Python列表是一种有顺序(ordered)的集合,每个元素都有一个位置,这个位置就是索引。列表中的元素位置是固定的,也就是说你每次访问这个列表,它的元素位置都不会变,除非用insert()、remove()等操作来改变列表。
不过,列表的顺序有可能并不是你真正需要的,或者说不是你这次需要的,有的时候你希望列表在使用前能按照你的需求先排个序,比如数字从小到大排序,字母按序排列。
sort( )方法排序
sort()会自动按照字母或数字从小到大的顺序排序。图1是将字母排序:
图1
代码①,对列表letters执行sort()方法,列表letters里的所有数据都会按照字母从小到大的顺序重新排序。
代码②,在执行过sort()方法后,打印列表letters,会看到列表letters里的值顺序已经和开始的不一样了,执行sort()方法后,列表letters里的值按从小到大的顺序重新排序了。
这是从小到大的顺序,但如果我们想从大到小逆序排列呢?我们只需在sort()函数里对带上参数reverse=True就可以了,见图2:
图2
代码①:对列表letters执行sort(revers=True)方法,列表letters里的所有数据都会按照字母从大到小的顺序重新排序。
特别强调:
sort()会对原列表进行修改,也就是说这个方法会改变原始列表,而不是创建一个新的有序列表。如果你想保留原来的顺序,只对列表的副本进行排序的话,可以使用另一种排序方法sorted()。
sorted( )方法排序
sorted()方法是对列表创建一个有序副本,这样不会影响原列表的顺序。见图3:
图3
代码① new_fruits=sorted(fruits):使用sorted()方法对列表fruits创建一个有序副本,并将这个有序副本列表赋值给变量new_fruits。
代码②:打印列表fruits,我们可以看到,列表fruits的值没有变化,还跟最初一样。
代码③:打印列表new_fruits,这个列表就是重新排过序的列表。
【特别强调:列表的副本问题】
关于使用sort()方法排序,我们都知道这种方法是对原列表做出修改,也就是说使用sort()方法排序后,列表各元素的位置就发生了变化,和原有的不一样了。如果想保留列表原有的顺序,对排过序的列表另外创建一个副本。
那有的小朋友可能会说了,可不可以先把这个列表赋值给一个变量,然后再对新赋值的那个列表排序呢?如图4:
图4
我们先创建了一个列表original,值为[4,5,3,2]。然后创建一个列表new,让它等于original,new=original(图4中的代码①)。之后我们print(new),可以看到列表new的值和列表original的值是一样的。
如果这时我们对列表new进行排序,会出现什么情况呢?见图5:
图5
我们会发现,当对列表new进行排序后(代码①new.sort()),不仅列表new的值发生了变化,就连original的值也跟着发生了变化。分别打印列表new(代码②)和列表original(代码③),我们看到两个列表都排序了,而不是只有我们以为的只有列表new排序了。
这是为什么呢?
① 当程序执行original=[4,5,3,2],实际上就是为[4,5,3,2]指定一个名字original,如图6。
图6
② 当我们执行new = original语句,其实就是为[4,5,3,2]指定另一个名字new,所以列表original和列表new实际上表示的是同一个列表,即使用这种方式不论指定多少个名字,其实列表始终都只有一个。如图7:
图7
③ 由于列表original和列表new指的是同一个列表,所以使用sort()方法对列表new排序,实际上值也影响original,毕竟他们指的是同一个列表。如图8:
图8
那如何解决我们想创建列表副本的需要呢?
最容易的方法是使用分片记法,如图9:
图9
代码① new_list = original_list[:],使用的就是分片记法,表示复制列表original_list中所有内容到列表new_list,从第一个元素到最后一个元素。执行print(new_list),可以看到列表new_list的值和列表original_list的值是一样的,但是这样得到的是两个列表,new_list是original_list的副本。见图10:
图10
然后我们对new_list排序,执行代码② new_list.sort()后,再分别打印new_list和original_list两个列表,会发现只有new_list排序了,original_list还是原样,也能为这已经是两个列表了,所以其中任意一个列表执行sort()操作,都不会影响另外一个。见图11:
图11
注意:
要特别说明的是,字典也存在和列表同样的问题,就是不能用等号创建副本。但假如这种操作发生在字符串或者数字类型呢?
如图12:
图12
先将“王老师”这个字符串赋值给变量myTeacher(代码①),然后执行yourTeacher=myTeacher,这时yourTeacher和myTeacher两个变量的值一样。其实就是一个内容有两个名字标签,如图13:
图13
但当我们修改myTeacher的值,将它的值改为“李老师”。实际上就相当于将名字标签myTeacher贴到“李老师”上,所以变量myTeacher的值是“李老师”,而变量yourTeacher的值不变,还是“王老师”。如图14:
图14
好了,你们搞清楚了吗?Python的排序以及列表副本的问题。