Python Cookbook 2——Python技巧
2017-01-10 21:27
267 查看
对象拷贝
new_list = copy.copy(existing_list)浅拷贝,虽然生成一个新对象,但是对象内部的属性和内容仍然引用原对象,一旦修改一个,两个均被改变。
new_list = copy.deepcopy(existing_list)深拷贝,修改new_list同时不改变existing_list。这种拷贝会消耗相当的时间和内存。
若列表中某元素存在则返回之
def list_get(L,i,v=None): if -len(L)<i<len(L): return L[i] else: return v def list_get(L,i,v=None): try: return L[i] except IndexError: return v #'获得原谅总是比获得许可容易(easier to get forgiveness than permission,EGFP)'
循环访问序列中的元素和索引
for i,j in enumerate(list)
d = dict(enumerate(L))利用enumerate将列表生成字典
展开一个嵌套的序列
def list_or_tuple(x): return isinstance(x,(list,tuple)) def flatten(sequence,to_expand=list_or_tuple): for item in sequence: if to_expand(item): for subitem in flatten(item,to_expand): yield subitem else: yield item l = [1,2,[3,4],5,[6]] for i in flatten(l): print i, out: 1 2 3 4 5 6
二维矩阵行列变换
1方案: a = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]] print [[i[j] for i in a]for j in xrange(len(a[0]))] out: [[1,4,7,10],[2,5,8,11],[3,6,9,12]] 2方案: print map(list,zip(*a))#达到目的,但晦涩难懂
在无需过多援引的情况下创建字典
d=dict(zip(the_keys,the_values))the_keys是键的序列,the_values是键对应的值的序列,内建的zip函数创建并返回一个数对(key,value)构成的列表,内建的dict接受这个列表作为参数并创建相应的字典。适合短序列。
对于长序列,可使用python标准库中的itertools模块提升速度。二者区别:zip会在内存中创建出包含所有数对的列表,而itertools.izip一次只生成一对数据。
import itertools d = dict(itertools.izip(the_keys,the_values))
将列表元素交替地作为键和值来创建字典
对扩展的列表切片调用内建函数zip:def dictFromList(d): return dict(zip(d[::2],d[1::2]))
更通用的适合任何序列或者可迭代参数的方式是:
def pairwise(iterable): itnext = iter(iterable).next while True: yield itnext(),itnext() def dictFromSequence(seq): return dict(pairwise(seq))
两种方法实质上是用同样的方法创建字典:都生成一个
(key,value)序列,并将其作为参数传递给dict。区别:
前者:使用切片操作,两个切片分别根据奇偶索引搜索元素。局限是:只支持扩展切片的类型或者类的实例,如list、tuple和str;且会在内存中创建临时列表,耗内存;
后者:使用生成器创建
(key,value)序列。适合任何可迭代对象list、tuple、str,还包括其他生成器的结果、文件、字典等。且一次只生成一对
(key,value),没有在内存中创建表,性能高。pairwise函数的实现:将内建函数iter应用于传入的iterable参数,获得一个迭代器,然后再将一个本地变量itnext绑定到这个迭代器的next方法。看上去有点奇怪,但这是python中一个很好的通用技巧:如果你有一个对象,你想对这个对象所做的事是在循环中不断调用它的一个方法,可以给它的这个被绑定的方法赋予一个本地的名字,然后就可以直接直接调用这个本地名字了,就像调用一个函数一样。
获取字典的一个子集
若不想改动原字典:def sub_dict(the_dict,somekeys,default=None): return dict((k,the_dict.get(k,default)) for k in somekeys) d = {'a': 1, 'c': 3, 'b': 2} sub_dict(d,'ab'),d out: {'a': 1, 'b': 2}, {'a': 1, 'c': 3, 'b': 2}
若想从原字典中删除那些符合条件的条目:
def sub_dict_remove(the_dict,somekeys,default=None): return dict((k,the_dict.pop(k,default)) for k in somekeys) d = {'a': 1, 'c': 3, 'b': 2} sub_dict_remove(d,'ab'),d out: {'a': 1, 'b': 2}, {'c': 3}
若键不匹配,抛出错误:
def sub_dict(the_dict,somekeys): return dict((k,the_dict[k]) for k in somekeys) def sub_dict_remove(the_dict,somekeys): return dict((k,the_dict.pop(k) for k in somekeys)
键不匹配时将其忽略:
def sub_dict(the_dict,somekeys): return dict((k,the_dict[k]) for k in somekeys if k in the_dict) def sub_dict_remove(the_dict,somekeys): return dict((k,the_dict.pop(k) for k in somekeys if k in the_dict)
字典的一键多值
允许键所对应的值重复:d1 = {} d1.setdefault(key,[]).append(value)#list作为字典的值 d1[key].remove(value)#删除键对应的值 d2 = {} d2.setdefault(key,{})[value1]=value2#子字典作为字典的值 del d2[key][value]
键所对应的值不可重复:
d3 = {} d3.setdefault(key,set()).add(value) d3[key]remove(value)
用字典分配方法和函数
在解决多分支语句时,常使用的方法是多个case或者if和else或者if和else if。但这种方法效率比较低,可读性不高。在python中,字典可使得多分支语句更容易被解决。具体的作法就是把在某个条件下要执行的过程写成一个函数,然后把该条件本身和对应的函数作为一对Key-Value放入一个字典中,该字典相当于一个Map。在别的语言中,可能需要使用case、switch、或者if else语句,但在python中,都可以使用字典的这个功能来解决。如:求一个数除以10的余数,并打印出来,可以这样写:
while True: n = raw_input() i = int(n) % 10 if i == 0: print 0 elif i == 1: print 1 elif i == 2: print 2 elif i == 3: print 3 elif i == 4: print 4 elif i == 5: print 5 elif i == 6: print 6 elif i == 7: print 7 elif i == 8: print 8 elif i == 9: print 9
使用字典来解决更方便:
def get0(): print 0 def get1(): print 1 def get2(): print 2 def get3(): print 3 def get4(): print 4 def get5(): print 5 def get6(): print 6 def get7(): print 7 def get8(): print 8 def get9(): print 9 dict = {0:get0, 1:get1, 2:get2, 3:get3, 4:get4, 5:get5, 6:get6, 7:get7, 8:get8, 9:get9} while True: n = raw_input() i = int(n) % 10 dict[i]()
字典的并集与交集
对于字典:a = dict.fromkeys(xrange(10))#dict.fromkeys来创建不考虑键对应的值 b = dict.fromkeys(xrange(5,15)) union = dict(a,**b)#交集 inter = dict.fromkeys(x for x in a if x in b)#并集
对于集合:
a = set(xrange(10)) b = set(xrange(5,15)) union = a | b / union = a.union(b)#交集 inter = a & b / inter = a.intersection(b)#并集
最好使用set类型而不是字典来代表集合。set能让代码更加直接、易读、清晰、高效。
即使由于某些原因使用了dict,也应当尽可能地使用set来完成集合操作。如:你有个字典phones(人名映射到电话号码),还有个字典addresses(人名映射到地址),需要打印所有知道地址和电话号码的人名、电话号码、地址:
for name in set(phones) & set(addresses): print name,phones[name],addresses[name] for name in set(phones).intersection(addresses): print name,phones[name],addresses[name] #如果使用intersection方法,就不需要将两个字典都转化为set,只需要其中一个,然后再对转化后的set调用intersection,并传入另一个dict作为intersection方法的参数。
相关文章推荐
- python 字符串技巧 from python cookbook
- Python Cookbook 第二版 汉化版 [Recipe 1.9] 简化字符串 translate 方法的用法
- Python Cookbook 4.1 复制(拷贝)对象(浅复制和深复制)
- Python Cookbook 第二版 汉化版 [00-2-Preface] Part 1
- Python Cookbook 第二版 汉化版 [Recipe 1.5] 去除字符串末尾的空格
- Python Cookbook 第二版 汉化版 [00-2-Preface] Part 2
- Python Cookbook 第二版 汉化版 [Recipe 1.8] 检测字符串是否包含特定的字符集合
- Python Cookbook 第二版 汉化版 [Recipe 16.4] 将参数与函数关联起来(Currying)
- Python Cookbook 第二版 汉化版 [Recipe 1.2] 字符与其对应的数字编码之间的转换
- Python Cookbook 第二版 汉化版 [Recipe 1.4] 对齐字符串
- Python Cookbook 第二版 汉化版 [Recipe 1.6] 字符串的组合
- Python Cookbook 第二版 汉化版 [Recipe 1.6] 字符串的组合
- Python Cookbook 第二版 汉化版 [00-1-Info]
- Python Cookbook 第二版 汉化版 [00-2-Preface] Part 2
- IronPython cookbook WebSite
- Python Cookbook 第二版 汉化版 [Recipe 1.5] 去除字符串末尾的空格
- Python Cookbook 第二版 汉化版 [00-2-Preface] Part 3
- Python Cookbook 第二版 汉化版 [Recipe 1.1] 逐个处理字符串中的各个字符
- Python Cookbook 第二版 汉化版 [Recipe 1.7] 以单词或字符为单位对字符串进行反序排列
- Python Cookbook 第二版 汉化版 [Recipe 1.1] 逐个处理字符串中的各个字符