python sort、sorted高级排序技巧
1. 简单的升序排序是非常容易的。只需要调用sorted()方法。它返回一个新的list,新的list的元素基于小于运算符(lt)来排序。
tips:sorted不会改变原序列
2. 你也可以使用list.sort()方法来排序,此时list本身将被修改。通常此方法不如sorted()方便,但是如果你不需要保留原来的list,此方法将更有效。
3. 另一个不同就是list.sort()方法仅被定义在list中,相反地sorted()方法对所有的可迭代序列都有效。所以后者使用更广泛。
4. list.sort()和sorted()函数增加了key参数来指定一个函数,此函数将在每个元素比较前被调用。 key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较。这个技术是快速的因为key指定的函数将准确地对每个元素调用。
5. list.sort()和sorted()都接受一个参数reverse(True or False)来表示升序或降序排序。
6. 从python2.2开始,排序被保证为稳定的。意思是说多个元素如果有相同的key,则排序前后他们的先后顺序不变。
7. 更复杂地你可以构建多个步骤来进行更复杂的排序,例如对student数据先按成绩排序,再按年龄排序。
上面的key参数的使用非常广泛,因此python提供了一些方便的函数来使得访问方法更加容易和快速。operator模块有itemgetter,attrgetter,从2.6开始还增加了methodcaller方法。operator模块还允许多级的排序,例如,先以grade,然后再以age来排序
DSU
第一:对原始的list进行装饰,使得新list的值可以用来控制排序;
第二:对装饰后的list排序;
第三:将装饰删除,将排序后的装饰list重新构建为原来类型的list;
例如,使用DSU方法来对student数据根据grade排序:
decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
decorated.sort()
[student for grade, i, student in decorated] # undecorate
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
上面的比较能够工作,原因是tuples是可以用来比较,tuples间的比较首先比较tuples的第一个元素,如果第一个相同再比较第二个元素,以此类推。
并不是所有的情况下都需要在以上的tuples中包含索引,但是包含索引可以有以下好处:
第一:排序是稳定的,如果两个元素有相同的key,则他们的原始先后顺序保持不变;
第二:原始的元素不必用来做比较,因为tuples的第一和第二元素用来比较已经是足够了。
此方法被RandalL.在perl中广泛推广后,他的另一个名字为也被称为Schwartzian transform。
对大的list或list的元素计算起来太过复杂的情况下,在python2.4前,DSU很可能是最快的排序方法。但是在2.4之后,上面解释的key函数提供了类似的功能。
Python numpy在保持行的整体性情况下排序
- 先逆序再转置a1 = a[:,::-1].T
- 以列整体性排序,从最后一行开始比较大小a2 = np.lexsort(a1)
- 取出排序序号a3 = a[a2]
- 按其他行可以进行行交换,类比列
调试期间看到这个:觉得对错误的分析很不错
读文件编码解码出错的时候,看到了这个文章不错,感谢虫师:http://www.cnblogs.com/fnng/p/5008884.html
认识常见编码
GB2312是中国规定的汉字编码,也可以说是简体中文的字符集编码
GBK 是 GB2312的扩展 ,除了兼容GB2312外,它还能显示繁体中文,还有日文的假名
cp936:中文本地系统是Windows中的cmd,默认codepage是CP936,cp936就是指系统里第936号编码格式,即GB2312的编码。
(当然有其它编码格式:cp950 繁体中文、cp932 日语、cp1250 中欧语言。。。)
Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。
UTF-8 (8-bit Unicode Transformation Format)是最流行的一种对 Unicode 进行传播和存储的编码方式。它用不同的 bytes 来表示每一个代码点。ASCII 字符每个只需要用一个 byte ,与 ASCII 的编码是一样的。所以说 ASCII 是 UTF-8 的一个子集。
字符串和日期相互转换
time和datetime
import time,datetime
# date to str
print time.strftime("%Y-%m-%d %X", time.localtime())
#str to date
t = time.strptime("2016 - 10 - 15", "%Y - %m - %d")
y,m,d = t[0:3]
print datetime.datetime(y,m,d)
常用的格式字符有:
%H: 小时(24小时制,[0, 23])
%m: 月份([01,12])
%M: 分钟([00,59])
%S: 秒(范围为[00,61],为什么不是[00, 59],参考python手册~_~)
%W: 周在当年的周数(是当年的第几周),星期一作为周的第一天
%Y: 4个数字表示的年份
%d: 日在这个月中的天数(是这个月的第几天)
Q:如何方便的计算两个时间的差,如两个时间相差几天,几小时等
A:使用datetime模块
import datetime
d1 = datetime.datetime(2005, 2, 16)
d2 = datetime.datetime(2004, 12, 31)
(d1 - d2).days
47
zip
zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple(元组),第0个元组对应于所有参数的第0个元素,第1个元组对应于所有参数的第1个元素,依此类推,然后返回由这些tuples组成的list(列表)。若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同。
zip([1,2,3,4],[5,6,7,8])会返回[(1, 5), (2, 6), (3, 7), (4, 8)]
但是如果输入的参数在一个列表当中,比如[[1,2,3,4],[5,6,7,8]],就需要进行解包裹,就是在传递列表时,让列表的每一个元素对应一个位置参数。在调用func时使用*,是为了提醒Python:我想要把args拆成分散的多个个元素,分别传递给多个位置参数。
l = [[1,2,3,4],[5,6,7,8]]
zip(*l)所实现的功能与上面的代码相同,只不过输入的参数有列表接包裹得到。返回的结果中,第一个元素恰好对应于输入列表的第一列,因此对返回的结果进行索引可以得到输入列表对应的列。
所以,能组合提取`
info = [[1,2,3,4],[5,6,7,8]]
key = zip(*info)[1]
key
(2, 6)
`