分分钟搞定Python之排序与列表
排序时程序中用得比较多的方法了。在Python中,最简单的排序方法摸过与使用内置的sorted(list)这个函数了,该函数一一个列表作为参数返回一个新的列表,只不过是把旧列表中的元素排过序了。原列表没有被改变。
a = [5, 1, 4, 3] print sorted(a) ## [1, 3, 4, 5] print a ## [5, 1, 4, 3]
我们最常用的酒杀给sorted函数传递一个列表,实际上它可以接受任何能迭代的集合作为参数。这里要注意list类型上的方法.sort(),它是在原列表上排序,没有返回值(正因为它不会生成一个新的列表,因此在速度上会较sorted快一点。不过你都能忍受python的速度了,这一点损耗当然就不是问题了)。相比之下,我们还是经常有sorted()方法,因为它的包容性更强大。
sorted()函数也带有一些自定义的参数,具体说明可以去看Python的官方文档(或者直接google关键字 python sorted)。这里简单的介绍下其中一个可选参数reverse,默认值为False,当为True的时候表示倒序排列.
strs = ['aa', 'BB', 'zz', 'CC'] print sorted(strs) ## ['BB', 'CC', 'aa', 'zz'] (case sensitive) print sorted(strs, reverse=True) ## ['zz', 'aa', 'CC', 'BB']
在实际应用的过程中,为了应对更复杂的排序要求,sorted()函数接受一个可选的参数key(通常是一个function,暂且称为key function)来确定排序时需要比较的方法。这个function有一个参数,返回一个值,而且这个返回值就用作排序比较时的标准。
来看下这个例子,对一个字符串的里诶包排序,我们指定这个key function为len函数,即用字符串的长度做为标准来排序,短的排在前面。
strs = ['ccc', 'aaaa', 'd', 'bb'] print sorted(strs, key=len) ## ['d', 'bb', 'ccc', 'aaaa']
来看另一个例子,我们用str.lower()作为排序的key function,来让所有字母都先变成小写再进行排序。
## "key" argument specifying str.lower function to use for sorting print sorted(strs, key=str.lower) ## ['aa', 'BB', 'CC', 'zz']
当然了,你也可以自己定义一恶搞函数来完成排序的功能。
## Say we have a list of strings we want to sort by the last letter of the string. strs = ['xc', 'zb', 'yd' ,'wa'] ## Write a little function that takes a string, and returns its last letter. ## This will be the key function (takes in 1 value, returns 1 value). def MyFn(s): return s[-1] ## Now pass key=MyFn to sorted() to sort by the last letter: print sorted(strs, key=MyFn) ## ['wa', 'zb', 'xc', 'yd']
当你使用key这个可选参数时,要谨记你提供的函数要接受一个参数并返回一个值来知道排序的标准。
好了,下面来说说list中一个比较屌的用法列表推导.这玩意用好了能帮你节约不少的代码量。列表推导是一种紧凑的表达式来扩展整个列表。假如我们有这样一个数字型的列表[1, 2, 3, ],我们的任务是计算每一项的平方[1, 4, 9, 16]
nums = [1, 2, 3, ] squares = [n*n for n in nums] ##[1, 4, 9, 16]
这个语法[expr for var in list]和语法[for var in list]长的很相似,但是前者没有后面的冒号: 语法左边的expr就是计算之前的每一项来应用到新的列表之中。再来看这样一个例子
strs = ['hello', 'and', 'goodbye'] shouting = [ s.upper() + '!!!' for s in strs ] ## ['HELLO!!!', 'AND!!!', 'GOODBYE!!!']
当然,你也可以在for-in后面加上if语句来过滤你原列表的每一项(只有这样子,才能称得上强大的工具对不对)。当if判断为true时就会代入到expr中进行下一步的计算。
## Select values <= 2 nums = [2, 8, 1, 6] small = [ n for n in nums if n <= 2 ] ## [2, 1] ## Select fruits containing 'a', change to upper case fruits = ['apple', 'cherry', 'bannana', 'lemon'] afruits = [ s.upper() for s in fruits if 'a' in s ] ## ['APPLE', 'BANNANA']