您的位置:首页 > 编程语言 > Python开发

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