python 黑魔法收集--已结
awesome python 中文大全
Fabric , pip, virtualenv
内建函数好文
awesome python
奇技淫巧
一句话求阶乘
from functools import reduce
reduce(lambda x, y: x * y, range(1,int(input('number:'))+1), 1)
# 递归
def factorial(n):
return 1 if n<=1 else n*factorial(n-1)
factorial = lambda x: 1 if x<=1 else x*factorial(x-1)
factorial(6)
from functools import reduce
print('\n'.join(map(lambda x: '{0:{1}<9}{0}{0:{1}>9}'.format(*('|','') if x%5 else ('+','-')),range(11))))
生成 26 个字母
''.join([ chr(i) for i in range(97,123)])
import string
string.ascii_lowercase
排列组合
# 排列
from itertools import permutations
a = [1,2,3]
b = permutations(a)
print(list(b))
# 组合
from itertools import combinations
for tuple_1 in [ i for i in combinations('abc', 2)]:
print(tuple_1)
给单词按首字母分组
方法一:
words = ['apple','bat','bar','atom','book']
by_letter_grp_dict = {}
for word in words:
letter = word[0]
if letter in by_letter_grp_dict:
by_letter_grp_dict[letter].append(word)
else:
by_letter_grp_dict[letter] = [word]
print(by_letter_grp_dict)
方法二:
内置的collections模块有一个叫做defaultdict的类,它可以使该过程更简单。传入一个类型或函数(用于生成字典各插槽所使用的默认值)即可创建一个defaultdict:
words = ['apple','bat','bar','atom','book']
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)
print by_letter
#defaultdict(<type 'list'>, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})
计数使用collections 库的 Counter
>>> from collections import Counter
>>> c = Counter('hello world!')
>>> c
Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1, '!': 1})
>>> c.most_common(1)
[('l', 3)]
>>> c.most_common(3)
[('l', 3), ('o', 2), ('h', 1)]
>>>
扩展拆箱
>>> a = [1,2,3,4,5,6]
>>> b,*c,d,e = a
>>> b
1
>>> c
[2, 3, 4]
>>> d
5
>>> e
6
和你的内存说再见
crash = dict(zip(range(10 **0xA), range(10 **0xA)))
扑克牌
>>> import collections
>>> Card = collections.namedtuple('Card',['rank','suit'])
>>> class French_Deck(object):
... rank = [ str(i) for i in range(2,11,1)] + list('JQKA')
... suit = 'Spade,Club,Heart,Diamond'.split(',')
... def __init__(self):
... self._cards = [Card(r,s) for s in suit for r in rank]
... def __getitem__(self,position):
... return self._cards[position]
... def __len__(self):
... return len(self._cards)
...
>>> cards = French_Deck()
>>> len(cards)
56
from collections import namedtuple
stock_list = [['AAPL','10.30','11.90'],['YAHO','9.23','8.19'],['SINA','22.80','25.80']]
stock_info = namedtuple('stock_info',['name','start','end'])
[stock_info(name,start,end) for name,start,end in stock_list ]
stock_list
# 与 update 不一样哦。。。
from collections import ChainMap
dict_1 = {'name':'Frank','age':18}
dict_2 = {'name':'','age':20}
dict_coalesce = ChainMap(dict_1,dict_2)
dict_coalesce['name']
#把列表分割成同样大小的块?
a = [1, 2, 3, 4, 5, 6]
list(zip( *[iter(a)]*2 ))
>>> [(1, 2), (3, 4), (5, 6)]
将列表按照某特定个数拆分成小列表
def chunks(l, n):
return [l[i:i+n] for i in range(0, len(l), n)]
chunks(s,2)
将字典的值转成object 的属性,递归
d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
def my_dict2obj(args):
class obj(object):
def __init__(self,d):
for key,value in d.items():
if not isinstance(value,(list,tuple)):
setattr(self,key,obj(value) if isinstance(value,dict) else value)
else:
setattr(self,key,[obj(i) if isinstance(i,dict) else i for i in value])
return obj(args)
x = my_dict2obj(d)
print(x.d)
# 合并list相邻项
a = [1, 2, 3, 4, 5, 6]
list(zip( a[::2], a[1::2] ))
>>> [(1, 2), (3, 4), (5, 6)]
# 合并字符串以及反序字符串
>>> s = ['a','b','c','d','e','f','g','h']
>>> ''.join(s)
'abcdefgh'
>>> ''.join(s[::-1])
'hgfedcba'
# 随机生成 5 个包含数字和字母的
>>> import random
>>> import string
>>> (random.choice(string.ascii_uppercase+string.digits) for _ in range(5))
<generator object <genexpr> at 0x03A0FEA0>
>>> for i in (random.choice(string.ascii_uppercase+string.digits) for _ in range(5)) :
... print(i)
...
K
8
E
V
0
使用生成器在读写文件时优化内存
def read_file(fpath):
BLOCK_SIZE = 1024
with open(fpath, 'rb') as f:
while True:
block = f.read(BLOCK_SIZE)
if block:
yield block
else:
return
In [35]: def groupby(items, size):
....: return zip(*[iter(items)]*size)
....:
In [36]: groupby(range(9), 3)
Out[36]: [(0, 1, 2), (3, 4, 5), (6, 7, 8)]
黑魔法收集
创建自己的 ORM 框架加深理解。
# 定义 Field 所有字段类的父类
class Field(object):
def __init__(self,name,column_type):
self.name = name
self.column_type = column_type
class StringField(Field):
def __init__(self,name):
# 此处的 StringField 是 type , self 是构造方法中调用必须传递的参数,就是规定!
return super(StringField,self).__init__(name,'varchar(100)')
class IntegerField(Field):
def __init__(self,name):
# 与上面 StringField 对应注释同理
return super(IntegerField,self).__init__(name,'bigint')
# 定义Model 及其子类的 元类 必须继承自 type,用于拼接动态sql 做 ORM 映射,没什么难的
class ModelMetaclass(type):
def __new__(cls,name,bases,attr_dict):
# 排除 Model 自己本身,只对它的子类进行映射
if(name == 'Model'):
return type.__new__(cls,name,bases,attr_dict)
print('Found Model {}'.format(name))
# 开始对子类进行属性与字段绑定
mappings = dict()
for key,value in attr_dict.items():
# 判断为 Field 类型的,就储存起来绑定
if isinstance(value,Field):
print('Found Field => {}'.format(key))
mappings[key] = value
# 为了防止 attrs_dict 中的实例属性覆盖类的属性,出栈这部分
for key in mappings.keys():
attr_dict.pop(key)
print('出栈实例属性 => {}'.format(key))
# 开始绑定 类属性与表中的字段 ,整个这么多工作只是为了下面两个绑定!!!
attr_dict['__mappings__'] = mappings
attr_dict['__table__'] = name
# 返回创建的心的对象
return type.__new__(cls,name,bases,attr_dict)
# 开始定义我们的 Model 类 继承自 dict 的原因? 思索,应该是调用它的dict[key] 方法, 关键在于 save 方法,如何从 mappings 中取出字符串并且拼接成 sql的
class Model(dict,metaclass = ModelMetaclass):
## 构造方法接收的是一个 属性字典集合 name='Tome',age=18,job='developer' 这种形式
def __init__(self,**kw):
super(Model,self).__init__(**kw)
# 获取属性值方法
def __getattr__(self,key):
return self[key] # 看此处 dict 的取值方法多方便
# 设置属性值方法
def __setattr__(self,key,value):
self[key] = value
def __replace__placeholder__(self,str_hold_placeholder,replace_str):
args_str = ''
j = 0
for i,v in enumerate(str_hold_placeholder):
s = v
if v == '?':
s = str(replace_str[j])
j = j+1
args_str = args_str + s
return args_str
# 拼接动态sql并保存到数据库中
def save(self):
fields=[]
args = []
params = []
table_name = self.__table__
for attr_key,attr_value in self.__mappings__.items():
fields.append(attr_key)
args.append(getattr(self,attr_key))
params.append('?')
dynamic_sql = 'insert into {}({}) values({})'.format(table_name,','.join(fields),','.join(params))
print(dynamic_sql)
print('args: {}'.format(args))
#封装替换占位符的方法
print(self.__replace__placeholder__(dynamic_sql,args))
# args_str = ''
# j = 0
# for i,v in enumerate(dynamic_sql):
# s = v
# if v == '?':
# s = str(args[j])
# j = j+1
# args_str = args_str + s
# print('args_str: ',args_str)
class User(Model):
# 定义类的属性到列的映射:
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password')
# 开始测试......
# 创建一个实例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
# 保存到数据库:
u.save()
输出结果如下:
Found Model User
Found Field => id
Found Field => email
Found Field => name
Found Field => password
出栈实例属性 => password
出栈实例属性 => name
出栈实例属性 => id
出栈实例属性 => email
insert into User(password,name,id,email) values(?,?,?,?)
args: ['my-pwd', 'Michael', 12345, 'test@orm.org']
insert into User(password,name,id,email) values(my-pwd,Michael,12345,test@orm.org)
为类的创建省略 self
from types import FunctionType
from byteplay import Code, opmap
def MetaClassFactory(function):
class MetaClass(type):
def __new__(meta, classname, bases, classDict):
for attributeName, attribute in classDict.items():
if type(attribute) == FunctionType:
attribute = function(attribute)
newClassDict[attributeName] = attribute
return type.__new__(meta, classname, bases, classDict)
return MetaClass
def _transmute(opcode, arg):
if ((opcode == opmap['LOAD_GLOBAL']) and
(arg == 'self')):
return opmap['LOAD_FAST'], arg
return opcode, arg
def selfless(function):
code = Code.from_code(function.func_code)
code.args = tuple(['self'] + list(code.args))
code.code = [_transmute(op, arg) for op, arg in code.code]
function.func_code = code.to_code()
return function
Selfless = MetaClassFactory(selfless)
class Test(object):
__metaclass__ = Selfless
def __init__(x=None):
self.x = x
def getX():
return self.x
def setX(x):
self.x = x
test = Test()
print(test.getX())
test.setX(7)
print(test.getX())
----------------------=补充=======-------------------
题目:
array = [1, 8, 15]
g = (x for x in array if array.count(x) > 0)
array = [2, 8, 22]
Output:
print(list(g))
[8]
问题:
为什么print 结果不是[1, 8, 15]呢??
解释:
在生成式表达式中,in 语句是在声明时进行评估的, 但是条件判断是运行时才进行操作。
所以在运行前,array 被分配给列表[1, 8, 15], 而运行时array被分配给列表[2, 8, 22]
两个不同时期列表中只有8是同时存在的,所以返回结果是8。
1、拆箱
2、拆箱变量交换
3、扩展拆箱(只兼容python3)
4、负数索引
5、 切割列表
6、 负数索引切割列表
7、指定步长切割列表
8、负数步长切割列表
9、列表切割赋值
10、 命名列表切割方式
11、列表以及迭代器的压缩和解压缩
关于怎么快速学python,可以加下小编的python学习群:611+530+101,不管你是小白还是大牛,小编我都欢迎,不定期分享干货
每天晚上20:00都会开直播给大家分享python学习知识和路线方法,群里会不定期更新最新的教程和学习方法,大家都是学习python的,或是转行,或是大学生,还有工作中想提升自己能力的,如果你是正在学习python的小伙伴可以加入学习。最后祝所有程序员都能够走上人生巅峰,让代码将梦想照进现实
12、列表相邻元素压缩器
13、在列表中用压缩器和迭代器滑动取值窗口
14、用压缩器反转字典
15、列表展开
16、 生成器表达式
17、字典推导
18、用字典推导反转字典
19、 命名元组
20、继承命名元组
21、操作集合
22、操作多重集合
23、统计在可迭代器中最常出现的元素
24、 两端都可操作的队列
25、有最大长度的双端队列
26、可排序词典
27、默认词典
28、默认字典的简单树状表达
29、 对象到唯一计数的映射
30、最大和最小的几个列表元素
31、 两个列表的笛卡尔积
32、列表组合和列表元素替代组合
33、列表元素排列组合
34、可链接迭代器
35、根据文件指定列类聚
显示有限的接口到外部
当发布python第三方package时, 并不希望代码中所有的函数或者class可以被外部import, 在__init__.py中添加__all__属性,
该list中填写可以import的类或者函数名, 可以起到限制的import的作用, 防止外部import其他函数或者类
Python
!/usr/bin/env python
-- coding: utf-8 --
from base import APIBase
from client import Client
from decorator import interface, export, stream
from server import Server
from storage import Storage
from util import (LogFormatter, disable_logging_to_stderr,
enable_logging_to_kids, info)
all = ['APIBase', 'Client', 'LogFormatter', 'Server',
'Storage', 'disable_logging_to_stderr', 'enable_logging_to_kids',
'export', 'info', 'interface', 'stream']
1
2
3
4
5
6
7
8
9
10
11
12
!/usr/bin/env python
-- coding: utf-8 --
from base import APIBase
from client import Client
from decorator import interface, export, stream
from server import Server
from storage import Storage
from util import (LogFormatter, disable_logging_to_stderr,
enable_logging_to_kids, info)
all = ['APIBase', 'Client', 'LogFormatter', 'Server',
'Storage', 'disable_logging_to_stderr', 'enable_logging_to_kids',
'export', 'info', 'interface', 'stream']
with的魔力
with语句需要支持上下文管理协议的对象, 上下文管理协议包含 enter 和 exit 两个方法. with语句建立运行时上下文需要通过这两个方法执行进入和退出操作.
其中上下文表达式是跟在with之后的表达式, 该表示大返回一个上下文管理对象
Python
常见with使用场景
with open("test.txt", "r") as my_file: # 注意, 是__enter__()方法的返回值赋值给了my_file,
for line in my_file:
print line
1
2
3
4
常见with使用场景
with open("test.txt", "r") as my_file: # 注意, 是__enter__()方法的返回值赋值给了my_file,
for line in my_file:
print line
详细原理可以查看这篇文章《浅谈 Python 的 with 语句》
知道具体原理, 我们可以自定义支持上下文管理协议的类, 类中实现 enter 和 exit 方法
Python
!/usr/bin/env python
-- coding: utf-8 --
class MyWith(object):
def init(self):
print "init method"
def enter(self):
print "enter method"
return self # 返回对象给as后的变量
def exit(self, exc_type, exc_value, exc_traceback):
print "exit method"
if exc_traceback is None:
print "Exited without Exception"
return True
else:
print "Exited with Exception"
return False
def test_with():
with MyWith() as my_with:
print "running my_with"
print "------分割线-----"
with MyWith() as my_with:
print "running before Exception"
raise Exception
print "running after Exception"
if name == 'main':
test_with()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
!/usr/bin/env python
-- coding: utf-8 --
class MyWith(object):
def init(self):
print "init method"
def enter(self):
print "enter method"
return self # 返回对象给as后的变量
def exit(self, exc_type, exc_value, exc_traceback):
print "exit method"
if exc_traceback is None:
print "Exited without Exception"
return True
else:
print "Exited with Exception"
return False
def test_with():
with MyWith() as my_with:
print "running my_with"
print "------分割线-----"
with MyWith() as my_with:
print "running before Exception"
raise Exception
print "running after Exception"
if name == 'main':
test_with()
执行结果如下:
init method
enter method
running my_with
exit method
Exited without Exception
------分割线-----
init method
enter method
running before Exception
exit method
Exited with Exception
Traceback (most recent call last):
File "bin/python", line 34, in
exec(compile(__file__f.read(), file, "exec"))
File "test_with.py", line 33, in
test_with()
File "test_with.py", line 28, in test_with
raise Exception
Exception
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
init method
enter method
running my_with
exit method
Exited without Exception
------分割线-----
init method
enter method
running before Exception
exit method
Exited with Exception
Traceback (most recent call last):
File "bin/python", line 34, in
exec(compile(__file__f.read(), file, "exec"))
File "test_with.py", line 33, in
test_with()
File "test_with.py", line 28, in test_with
raise Exception
Exception
证明了会先执行 enter 方法, 然后调用with内的逻辑, 最后执行 exit 做退出处理, 并且, 即使出现异常也能正常退出
filter的用法
相对filter而言, map和reduce使用的会更频繁一些, filter正如其名字, 按照某种规则过滤掉一些元素
Python
!/usr/bin/env python
-- coding: utf-8 --
lst = [1, 2, 3, 4, 5, 6]
所有奇数都会返回True, 偶数会返回False被过滤掉
print filter(lambda x: x % 2 != 0, lst)
输出结果
[1, 3, 5]
1
2
3
4
5
6
7
!/usr/bin/env python
-- coding: utf-8 --
lst = [1, 2, 3, 4, 5, 6]
所有奇数都会返回True, 偶数会返回False被过滤掉
print filter(lambda x: x % 2 != 0, lst)
输出结果
[1, 3, 5]
一行作判断
当条件满足时, 返回的为等号后面的变量, 否则返回else后语句
Python
lst = [1, 2, 3]
new_lst = lst[0] if lst is not None else None
print new_lst
打印结果
1
1
2
3
4
5
lst = [1, 2, 3]
new_lst = lst[0] if lst is not None else None
print new_lst
打印结果
1
装饰器之单例
使用装饰器实现简单的单例模式
Python
单例装饰器
def singleton(cls):
instances = dict() # 初始为空
def _singleton(args, **kwargs):
if cls not in instances: #如果不存在, 则创建并放入字典
instances[cls] = cls(args, **kwargs)
return instances[cls]
return _singleton
@singleton
class Test(object):
pass
if name == 'main':
t1 = Test()
t2 = Test()
# 两者具有相同的地址
print t1, t2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
单例装饰器
def singleton(cls):
instances = dict() # 初始为空
def _singleton(args, **kwargs):
if cls not in instances: #如果不存在, 则创建并放入字典
instances[cls] = cls(args, **kwargs)
return instances[cls]
return _singleton
@singleton
class Test(object):
pass
if name == 'main':
t1 = Test()
t2 = Test()
# 两者具有相同的地址
print t1, t2
staticmethod装饰器
类中两种常用的装饰, 首先区分一下他们
普通成员函数, 其中第一个隐式参数为对象
classmethod装饰器, 类方法(给人感觉非常类似于OC中的类方法), 其中第一个隐式参数为类
staticmethod装饰器, 没有任何隐式参数. python中的静态方法类似与C++中的静态方法
Python
!/usr/bin/env python
-- coding: utf-8 --
class A(object):
# 普通成员函数
def foo(self, x):
print "executing foo(%s, %s)" % (self, x)
@classmethod # 使用classmethod进行装饰
def class_foo(cls, x):
print "executing class_foo(%s, %s)" % (cls, x)
@staticmethod # 使用staticmethod进行装饰
def static_foo(x):
print "executing static_foo(%s)" % x
def test_three_method():
obj = A()
# 直接调用噗通的成员方法
obj.foo("para") # 此处obj对象作为成员函数的隐式参数, 就是self
obj.class_foo("para") # 此处类作为隐式参数被传入, 就是cls
A.class_foo("para") #更直接的类方法调用
obj.static_foo("para") # 静态方法并没有任何隐式参数, 但是要通过对象或者类进行调用
A.static_foo("para")
if name == 'main':
test_three_method()
函数输出
executing foo(<main.A object at 0x100ba4e10>, para)
executing class_foo(<class 'main.A'>, para)
executing class_foo(<class 'main.A'>, para)
executing static_foo(para)
executing static_foo(para)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
!/usr/bin/env python
-- coding: utf-8 --
class A(object):
# 普通成员函数
def foo(self, x):
print "executing foo(%s, %s)" % (self, x)
@classmethod # 使用classmethod进行装饰
def class_foo(cls, x):
print "executing class_foo(%s, %s)" % (cls, x)
@staticmethod # 使用staticmethod进行装饰
def static_foo(x):
print "executing static_foo(%s)" % x
def test_three_method():
obj = A()
# 直接调用噗通的成员方法
obj.foo("para") # 此处obj对象作为成员函数的隐式参数, 就是self
obj.class_foo("para") # 此处类作为隐式参数被传入, 就是cls
A.class_foo("para") #更直接的类方法调用
obj.static_foo("para") # 静态方法并没有任何隐式参数, 但是要通过对象或者类进行调用
A.static_foo("para")
if name == 'main':
test_three_method()
函数输出
executing foo(<main.A object at 0x100ba4e10>, para)
executing class_foo(<class 'main.A'>, para)
executing class_foo(<class 'main.A'>, para)
executing static_foo(para)
executing static_foo(para)
property装饰器
定义私有类属性
将property与装饰器结合实现属性私有化(更简单安全的实现get和set方法)
Python
python内建函数
property(fget=None, fset=None, fdel=None, doc=None)
1
2
python内建函数
property(fget=None, fset=None, fdel=None, doc=None)
fget是获取属性的值的函数,fset是设置属性值的函数,fdel是删除属性的函数,doc是一个字符串(like a comment).从实现来看,这些参数都是可选的
property有三个方法getter(), setter()和delete() 来指定fget, fset和fdel。 这表示以下这行
Python
class Student(object):
@property #相当于property.getter(score) 或者property(score)
def score(self):
return self._score
@score.setter #相当于score = property.setter(score)
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
1
2
3
4
5
6
7
8
9
10
11
class Student(object):
@property #相当于property.getter(score) 或者property(score)
def score(self):
return self._score
@score.setter #相当于score = property.setter(score)
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
iter魔法
通过yield和__iter__的结合, 我们可以把一个对象变成可迭代的
通过__str__的重写, 可以直接通过想要的形式打印对象
Python
!/usr/bin/env python
-- coding: utf-8 --
class TestIter(object):
def init(self):
self.lst = [1, 2, 3, 4, 5]
def read(self):
for ele in xrange(len(self.lst)):
yield ele
def iter(self):
return self.read()
def str(self):
return ','.join(map(str, self.lst))
__repr__ = __str__
def test_iter():
obj = TestIter()
for num in obj:
print num
print obj
if name == 'main':
test_iter()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
!/usr/bin/env python
-- coding: utf-8 --
class TestIter(object):
def init(self):
self.lst = [1, 2, 3, 4, 5]
def read(self):
for ele in xrange(len(self.lst)):
yield ele
def iter(self):
return self.read()
def str(self):
return ','.join(map(str, self.lst))
__repr__ = __str__
def test_iter():
obj = TestIter()
for num in obj:
print num
print obj
if name == 'main':
test_iter()
神奇partial
partial使用上很像C++中仿函数(函数对象).
在stackoverflow给出了类似与partial的运行方式
Python
def partial(func, part_args):
def wrapper(extra_args):
args = list(part_args)
args.extend(extra_args)
return func(args)
return wrapper
1
2
3
4
5
6
def partial(func, part_args):
def wrapper(extra_args):
args = list(part_args)
args.extend(extra_args)
return func(args)
return wrapper
利用用闭包的特性绑定预先绑定一些函数参数, 返回一个可调用的变量, 直到真正的调用执行
Python
!/usr/bin/env python
-- coding: utf-8 --
from functools import partial
def sum(a, b):
return a + b
def test_partial():
fun = partial(sum, 2) # 事先绑定一个参数, fun成为一个只需要一个参数的可调用变量
print fun(3) # 实现执行的即是sum(2, 3)
if name == 'main':
test_partial()
执行结果
5
1
2
3
4
5
6
7
8
9
10
11
12
13
!/usr/bin/env python
-- coding: utf-8 --
from functools import partial
def sum(a, b):
return a + b
def test_partial():
fun = partial(sum, 2) # 事先绑定一个参数, fun成为一个只需要一个参数的可调用变量
print fun(3) # 实现执行的即是sum(2, 3)
if name == 'main':
test_partial()
执行结果
5
神秘eval
eval我理解为一种内嵌的python解释器(这种解释可能会有偏差), 会解释字符串为对应的代码并执行, 并且将执行结果返回
看一下下面这个例子
Python
!/usr/bin/env python
-- coding: utf-8 --
def test_first():
return 3
def test_second(num):
return num
action = { # 可以看做是一个sandbox
"para": 5,
"test_first" : test_first,
"test_second": test_second
}
def test_eavl():
condition = "para == 5 and test_second(test_first) > 5"
res = eval(condition, action) # 解释condition并根据action对应的动作执行
print res
if name == '_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
!/usr/bin/env python
-- coding: utf-8 --
def test_first():
return 3
def test_second(num):
return num
action = { # 可以看做是一个sandbox
"para": 5,
"test_first" : test_first,
"test_second": test_second
}
def test_eavl():
condition = "para == 5 and test_second(test_first) > 5"
res = eval(condition, action) # 解释condition并根据action对应的动作执行
print res
if name == '_
exec
exec在Python中会忽略返回值, 总是返回None, eval会返回执行代码或语句的返回值
exec和eval在执行代码时, 除了返回值其他行为都相同
在传入字符串时, 会使用compile(source, '
Python
!/usr/bin/env python
-- coding: utf-8 --
def test_first():
print "hello"
def test_second():
test_first()
print "second"
def test_third():
print "third"
action = {
"test_second": test_second,
"test_third": test_third
}
def test_exec():
exec "test_second" in action
if name == 'main':
test_exec() # 无法看到执行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
!/usr/bin/env python
-- coding: utf-8 --
def test_first():
print "hello"
def test_second():
test_first()
print "second"
def test_third():
print "third"
action = {
"test_second": test_second,
"test_third": test_third
}
def test_exec():
exec "test_second" in action
if name == 'main':
test_exec() # 无法看到执行结果
getattr
getattr(object, name[, default])Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, ‘foobar’) is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.
通过string类型的name, 返回对象的name属性(方法)对应的值, 如果属性不存在, 则返回默认值, 相当于object.name
Python
使用范例
class TestGetAttr(object):
test = "test attribute"
def say(self):
print "test method"
def test_getattr():
my_test = TestGetAttr()
try:
print getattr(my_test, "test")
except AttributeError:
print "Attribute Error!"
try:
getattr(my_test, "say")()
except AttributeError: # 没有该属性, 且没有指定返回值的情况下
print "Method Error!"
if name == 'main':
test_getattr()
输出结果
test attribute
test method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
使用范例
class TestGetAttr(object):
test = "test attribute"
def say(self):
print "test method"
def test_getattr():
my_test = TestGetAttr()
try:
print getattr(my_test, "test")
except AttributeError:
print "Attribute Error!"
try:
getattr(my_test, "say")()
except AttributeError: # 没有该属性, 且没有指定返回值的情况下
print "Method Error!"
if name == 'main':
test_getattr()
输出结果
test attribute
test method
命令行处理
Python
def process_command_line(argv):
"""
Return a 2-tuple: (settings object, args list).
argv
is a list of arguments, or None
for sys.argv[1:]
.
"""
if argv is None:
argv = sys.argv[1:]
# initialize the parser object:
parser = optparse.OptionParser(
formatter=optparse.TitledHelpFormatter(width=78),
add_help_option=None)
# define options here:
parser.add_option( # customized description; put --help last
'-h', '--help', action='help',
help='Show this help message and exit.')
settings, args = parser.parse_args(argv)
# check number of arguments, verify values, etc.:
if args:
parser.error('program takes no command-line arguments; '
'"%s" ignored.' % (args,))
# further process settings & args if necessary
return settings, args
def main(argv=None):
settings, args = process_command_line(argv)
# application code here, like:
# run(settings, args)
return 0 # success
if name == 'main':
status = main()
sys.exit(status)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def process_command_line(argv):
"""
Return a 2-tuple: (settings object, args list).
argv
is a list of arguments, or None
for sys.argv[1:]
.
"""
if argv is None:
argv = sys.argv[1:]
# initialize the parser object:
parser = optparse.OptionParser(
formatter=optparse.TitledHelpFormatter(width=78),
add_help_option=None)
# define options here:
parser.add_option( # customized description; put --help last
'-h', '--help', action='help',
help='Show this help message and exit.')
settings, args = parser.parse_args(argv)
# check number of arguments, verify values, etc.:
if args:
parser.error('program takes no command-line arguments; '
'"%s" ignored.' % (args,))
# further process settings & args if necessary
return settings, args
def main(argv=None):
settings, args = process_command_line(argv)
# application code here, like:
# run(settings, args)
return 0 # success
if name == 'main':
status = main()
sys.exit(status)
读写csv文件
Python
从csv中读取文件, 基本和传统文件读取类似
import csv
with open('data.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
print row
向csv文件写入
import csv
with open( 'data.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerow(['name', 'address', 'age']) # 单行写入
data = [
( 'xiaoming ','china','10'),
( 'Lily', 'USA', '12')]
writer.writerows(data) # 多行写入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
从csv中读取文件, 基本和传统文件读取类似
import csv
with open('data.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
print row
向csv文件写入
import csv
with open( 'data.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerow(['name', 'address', 'age']) # 单行写入
data = [
( 'xiaoming ','china','10'),
( 'Lily', 'USA', '12')]
writer.writerows(data) # 多行写入
各种时间形式转换
只发一张网上的图, 然后差文档就好了, 这个是记不住的
字符串格式化
一个非常好用, 很多人又不知道的功能
Python
name = "andrew"
"my name is {name}".format(name=name)
'my name is andrew'
1
2
3
name = "andrew"
"my name is {name}".format(name=name)
'my name is andrew'
Python编码规范(PEP8)及奇技淫巧(不断更新)
2017年04月04日 19:18:00
阅读数:4309
Python 2.7
前言
从很多地方搬运+总结,以后根据这个标准再将python的一些奇技淫巧结合起来,写出更pythonic的代码~
PEP8 编码规范
英文原版请点击这里
以下是@bobo的整理,原文请见PEP8 Python 编码规范整理
代码编排
缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。
文档编排
模块内容的顺序:模块说明和docstring—import—globals&constants—其他定义。其中import部分,又按标准、三方和自己编写顺序依次排放,之间空一行
不要在一句import中多个库,比如import os, sys不推荐
如果采用from XX import XX引用库,可以省略‘module.’,都是可能出现命名冲突,这时就要采用import XX
空格的使用
各种右括号前不要加空格。
逗号、冒号、分号前不要加空格。
函数的左括号前不要加空格。如Func(1)
序列的左括号前不要加空格。如list[2]
操作符左右各加一个空格,不要为了对齐增加空格
函数默认参数使用的赋值符左右省略空格
不要将多句语句写在同一行,尽管使用‘;’允许
if/for/while语句中,即使执行语句只有一句,也必须另起一行
注释
总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释!注释必须使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。如果是短语,可以省略结束符。
块注释,在一段代码前增加的注释。在‘#’后加一空格。段落之间以只有‘#’的行间隔。比如:
Description : Module config.
Input : None
Output : None
1
2
3
4
5
行注释,在一句代码后加注释。比如:x = x + 1 # Increment x但是这种方式尽量少使用。
避免无谓的注释。
文档描述
为所有的共有模块、函数、类、方法写docstrings;非共有的没有必要,但是可以写注释(在def的下一行)。
单行注释请参考如下方式
def kos_root():
"""Return the pathname of the KOS root directory."""
global _kos_root
if _kos_root: return _kos_root
...
1
2
3
4
5
命名规则
- 总体原则,新编代码必须按下面命名风格进行,现有库的编码尽量保持风格。绝不要单独使用例如大写的’i’和大写的’o’*
模块命名尽量短小,使用全部小写的方式,可以使用下划线。
包命名尽量短小,使用全部小写的方式,不可以使用下划线。
类的命名使用CapWords的方式,模块内部使用的类采用_CapWords的方式。
异常命名使用CapWords+Error后缀的方式。
全局变量尽量只在模块内有效,类似C语言中的static。实现方法有两种,一是all机制;二是前缀一个下划线。
函数命名使用全部小写的方式,可以使用下划线。
常量命名使用全部大写的方式,可以使用下划线。
类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。
类的属性有3种作用域public、non-public和subclass API,可以理解成C++中的public、private、protected,non-public属性前,前缀一条下划线。
类的属性若与关键字名字冲突,后缀一下划线,尽量不要使用缩略等其他方式。
为避免与子类属性命名冲突,在类的一些属性前,前缀两条下划线。比如:类Foo中声明__a,访问时,只能通过Foo._Foo__a,避免歧义。如果子类也叫Foo,那就无能为力了。
类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。
编程建议
编码中考虑到其他python实现的效率等问题,比如运算符‘+’在CPython(Python)中效率很高,都是Jython中却非常低,所以应该采用.join()的方式。
尽可能使用‘is’‘is not’取代‘==’,比如if x is not None 要优于if x
使用基于类的异常,每个模块或包都有自己的异常类,此异常类继承自Exception。
常中不要使用裸露的except,except后跟具体的exceptions。例如
try:
...
except Exception as ex:
print ex
1
2
3
4
异常中try的代码尽可能少。
使用startswith() and endswith()代替切片进行序列前缀或后缀的检查。
foo = 'abc000xyz'
if foo.startswith('abc') and foo.endswith('xyz'):
print 'yes'
else:
print 'no'
yes
而如下的方式不提倡
if foo[:3]'abc' and foo[-3:]'xyz':
print 'yes'
else:
print 'no'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
使用isinstance()比较对象的类型。比如:
foo = 'abc000xyz'
提倡
print isinstance(foo,int) # false
不提倡
print type(foo) == type('1') #true
1
2
3
4
5
6
7
判断序列空或不空,有如下规则:
foo = 'abc000xyz'
if foo:
print "not empty"
else:
print "empty"
不提倡使用如下
if len(foo):
print "not empty"
else:
print "empty"
1
2
3
4
5
6
7
8
9
10
11
12
二进制数据判断使用 if boolvalue的方式。
给自己的代码打分
使用pylint进行代码检查,@permilk–Python代码分析工具:PyChecker、Pylint
安装
pip install pylint
1
2
写一段测试代码,命名为test.py
-- coding:utf-8 --
原理:http://blog.csdn.net/morewindows/article/details/6684558
代码提供: http://www.cnblogs.com/yekwol/p/5778040.html
def parttion(vec, left, right):
key = vec[left]
low = left
high = right
while low < high:
while (low < high) and (vec[high] >= key):
high -= 1
vec[low] = vec[high]
while (low < high) and (vec[low] <= key):
low += 1
vec[high] = vec[low]
vec[low] = key
return low
采用递归的方式进行函数构建
def quicksort(vec, left, right):
if left < right:
p = parttion(vec, left, right)
quicksort(vec, left, p-1) # 再同样处理分片问题
quicksort(vec, p+1, right)
return vec
s = [6, 8, 1, 4, 3, 9, 5, 4, 11, 2, 2, 15, 6]
before_list = [4, 6, 1, 3, 5, 9]
print "before sort:", before_list
after_list = quicksort(before_list, left=0, right=len(before_list)-1)
print"after sort:", after_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
进行代码规范测试
使用
pylint test.py
输出
Problem importing module variables.py: No module named functools_lru_cache
Problem importing module variables.pyc: No module named functools_lru_cache
No config file found, using default configuration
************* Module test
C: 24, 0: Trailing whitespace (trailing-whitespace)
C: 1, 0: Missing module docstring (missing-docstring)
C: 5, 0: Missing function docstring (missing-docstring)
C: 20, 0: Missing function docstring (missing-docstring)
C: 22, 8: Invalid variable name "p" (invalid-name)
C: 28, 0: Invalid constant name "before_list" (invalid-name)
C: 30, 0: Invalid constant name "after_list" (invalid-name)
Report
23 statements analysed.
Statistics by type
+---------+-------+-----------+-----------+------------+---------+
|type |number |old number |difference |%documented |%badname |
+=+=+=+=+==+=+
|module |1 |1 |= |0.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
|class |0 |0 |= |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
|method |0 |0 |= |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
|function |2 |2 |= |0.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
Raw metrics
+----------+-------+------+---------+-----------+
|type |number |% |previous |difference |
++=++=+=====+
|code |23 |71.88 |23 |= |
+----------+-------+------+---------+-----------+
|docstring |0 |0.00 |0 |= |
+----------+-------+------+---------+-----------+
|comment |5 |15.62 |5 |= |
+----------+-------+------+---------+-----------+
|empty |4 |12.50 |4 |= |
+----------+-------+------+---------+-----------+
Duplication
+-------------------------+------+---------+-----------+
| |now |previous |difference |
+=++=+=+
|nb duplicated lines |0 |0 |= |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000 |= |
+-------------------------+------+---------+-----------+
Messages by category
+-----------+-------+---------+-----------+
|type |number |previous |difference |
+=+=+=+=======+
|convention |7 |7 |= |
+-----------+-------+---------+-----------+
|refactor |0 |0 |= |
+-----------+-------+---------+-----------+
|warning |0 |0 |= |
+-----------+-------+---------+-----------+
|error |0 |0 |= |
+-----------+-------+---------+-----------+
Messages
+--------------------+------------+
|message id |occurrences |
+========++
|missing-docstring |3 |
+--------------------+------------+
|invalid-name |3 |
+--------------------+------------+
|trailing-whitespace |1 |
+--------------------+------------+
Global evaluation
Your code has been rated at 6.96/10 (previous run: 6.96/10, +0.00)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
Python奇技淫巧
使用 Counter 进行计数统计
from collections import Counter
Counter(s=3, c=2, e=1, u=1)
Counter({'s': 3, 'c': 2, 'u': 1, 'e': 1})
some_data=('c', '2', 2, 3, 5, 'c', 'd', 4, 5, 'd', 'd')
Counter(some_data).most_common(2)
[('d', 3), ('c', 2)]
some_data=['c', '2', 2, 3, 5, 'c', 'd', 4, 5, 'd', 'd']
Counter(some_data).most_common(2)
[('d', 3), ('c', 2)]
some_data={'c', '2', 2, 3, 5, 'c', 'd', 4, 5, 'd', 'd'}
Counter(some_data).most_common(2)
[('c', 1), (3, 1)]
1
2
3
4
5
6
7
8
9
10
11
12
13
enumerate获取键值对
在同时需要index和value值的时候可以使用 enumerate。下列分别将字符串,数组,列表与字典遍历序列中的元素以及它们的下标
for i,j in enumerate('abcde'):
... print i,j
...
0 a
1 b
2 c
3 d
4 e
for i,j in enumerate([1,2,3,4]):
... print i,j
...
0 1
1 2
2 3
3 4
for i,j in enumerate([1,2,3,4],start=1):
... print i,j
...
1 1
2 2
3 3
4 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
通过键索引来追踪元素
from collections import defaultdict
s = "the quick brown fox jumps over the lazy dog"
words = s.split()
location = defaultdict(list)
for m, n in enumerate(words):
location[n].append(m)
print location
defaultdict(<type 'list'>, {'brown': [2], 'lazy': [7], 'over': [5], 'fox': [3],
'dog': [8], 'quick': [1], 'the': [0, 6], 'jumps': [4]})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
os.path的使用
os.path.join用于拼接路径,好处是可以根据系统自动选择正确的路径分隔符”/”或”\”
os.path.split 把路径分割成dirname和basename,返回一个元组
os.listdir 获取路径下所有文件,返回list
import os
path=os.path.abspath("ams8B.zip")
print path # /Users/didi/Desktop/testhelp/ams8B.zip # 实际上该文件夹下没有ams8B.zip
print os.path.join("/".join(path.split("/")[:-1]),'ams8B.gz') # /Users/didi/Desktop/testhelp/ams8B.gz
print os.path.join("home","user","test") # home/user/test
把路径分割成dirname和basename,返回一个元组,作用在于不用区别到底是''还是'/'
print os.path.split(path) # ('/Users/didi/Desktop/testhelp', 'ams8B.zip')
print os.path.join(os.path.split(path)[0],'ams8B.gz') # /Users/didi/Desktop/testhelp/ams8B.gz
print os.getcwd() # /Users/didi/Desktop/testhelp
print os.listdir(os.getcwd()) # ['t1.txt', 'test1.py', 'test2.py', '\xe6\x8e\xa5\xe9\xa9\xbeeta\xe5\x88\x86\xe5\xb8\x83.sh']
1
2
3
4
5
6
7
8
9
10
11
善用列表推导式
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]print map(lambda x: x * 2 + 10, foo)
[14, 46, 28, 54, 44, 58, 26, 34, 64]print reduce(lambda x, y: x + y, foo)
139
1
2
3
4
5
6
7
8
9
使用列表推导式
[x * 2 + 10 for x in foo]
[14, 46, 28, 54, 44, 58, 26, 34, 64]
[x for x in foo if x % 3 == 0]
[18, 9, 24, 12, 27]
1
2
3
4
对于轻量级循环,可尽量使用列表推导式,熟练使用列表推导式可以很多情况下代替map,filter等
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
foo
[2, 18, 9, 22, 17, 24, 8, 12, 27]
['>3' if i>3 else '❤️' for i in foo]
['❤️', '>3', '>3', '>3', '>3', '>3', '>3', '>3', '>3']
t=map(lambda x:'❤️' if x<3 else '>3',foo)
t
['❤️', '>3', '>3', '>3', '>3', '>3', '>3', '>3', '>3']
1
2
3
4
5
6
7
8
9
可参考:最简单的理解lambda,map,reduce,filter,列表推导式
sort 与 sorted
函数原型
sorted(iterable[, cmp[, key[, reverse]]]) # 返回一个排序后的列表
s.sort([cmp[, key[, reverse]]]) # 直接修改原列表,返回为None
persons = [{'name': 'Jon', 'age': 32}, {'name': 'Alan', 'age': 50}, {'name': 'Bob', 'age': 23}]
sorted(persons, key=lambda x: (x['name'], -x['age']))
[{'name': 'Alan', 'age': 50}, {'name': 'Bob', 'age': 23}, {'name': 'Jon', 'age': 32}]
a = (1, 2, 4, 2, 3)
sorted(a)
[1, 2, 2, 3, 4]
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10),]
sorted(students, key=lambda student : student[2]) # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
1
2
3
4
5
6
7
8
9
10
11
12
13
所以如果实际过程中需要保留原有列表,可以使用sorted()。sort()不需要复制原有列表,消耗内存较小,效率较高。同时传入参数key比传入参数cmp效率要高,cmp传入的函数在整个排序过程中会调用多次,而key针对每个元素仅作一次处理。
关于cmp的使用,这位哥们总算踩到点python中sort()方法自定义cmp PythonTip-最大正整数
cmp --如果排序的元素是其他类型的,如果a逻辑小于b,函数返回负数;a逻辑等于b,函数返回0;a逻辑大于b,函数返回正数就行了,这决定着两者是否交换位置
def Reverse(a,b):
return b-a
list_ = [5,3,4,1,2]
new = sorted(list_,cmp=ps)
print new # [5, 4, 3, 2, 1]
这里的例子是,5,3做差值,为负,故两者不交换位置,里面的return作为条件
1
2
3
4
5
6
7
8
9
10
善用traceback 追踪深层错误
import traceback
try:
do something
except Exception as ex:
print ex
traceback.print_exc()
1
2
3
4
5
6
7
8
切片操作[]
相当于浅copy的作用
a=[1,2,3]
b=a[:]
b.append(4)
b
[1, 2, 3, 4]
a
[1, 2, 3]
import copy
c=copy.copy(a)
c
[1, 2, 3]
c.append(4)
a
[1, 2, 3]
c
[1, 2, 3, 4]
d=a
d.append(4)
d
[1, 2, 3, 4]
a
[1, 2, 3, 4]
这里顺便说下deepcopy
理论部分可以参考这里
浅copy
import copy
a = [[1,2],3,4]
b = copy.copy(a)
id(a)
54936008L
id(b)
54964680L
a is b
False
b
[[1, 2], 3, 4]
b[0][1]
2
b[0][1]=2333
b
[[1, 2333], 3, 4]
a
[[1, 2333], 3, 4]
deepcopy
a = [[1,2],3,4]
c = copy.deepcopy(a)
id(a)
55104008L
id(c)
54974536L
a is c
False
c
[[1, 2], 3, 4]
c[0][1]
2
c[0][1]=233
c
[[1, 233], 3, 4]
a
[[1, 2], 3, 4] # 不会随之改变
这里测试下切片操作相当于浅copy
d = a[:]
d
[[1, 2], 3, 4]
d[0][1]=0
d
[[1, 0], 3, 4]
a
[[1, 0], 3, 4] # 会随之改变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
进行逆序排列
b
[1, 2, 3, 4]
b[::-1]
[4, 3, 2, 1]
1
2
3
4
json.dump()/loads() 存储字典结构
json.dumps : dict转成str
json.loads:str转成dict
import json
dict_ = {1:2, 3:4, "55":"66"}
json_str = json.dumps(dict_)
print type(json_str), json_str
<type 'str'>
print type(json.loads(json_str))
<type 'dict'>
1
2
3
4
5
6
7
8
9
10
11
pprint打印结构
from pprint import pprint
data = [(1,{'a':'A','b':'B','c':'C','d'😂'}),
(2,{'e':'E','f':'F','g':'G','h':'H',
'i':'I','j':'J','k':'K','l':'L'
}),]
print data
pprint(data)
print效果
[(1, {'a': 'A', 'c': 'C', 'b': 'B', 'd': 'D'}), (2, {'e': 'E', 'g': 'G', 'f': 'F', 'i': 'I', 'h': 'H', 'k': 'K', 'j': 'J', 'l': 'L'})]
pprint效果
[(1, {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D'}),
(2,
{'e': 'E',
'f': 'F',
'g': 'G',
'h': 'H',
'i': 'I',
'j': 'J',
'k': 'K',
'l': 'L'})]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
zip打包元组
定义:zip([seql, …])接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list(列表)。若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同。
!/usr/bin/python
-- coding: utf-8 --
name = ['mrlevo','hasky']
kind = ['human','dog']
z1 = [1,2,3]
z2 = [4,5,6]
result = zip(z1,z2) # 压缩过程
uzip= zip(*result) # 解压过程,拆分为元组
print "the zip:",result
the zip: [(1, 4), (2, 5), (3, 6)]
print "the uzip:",uzip
the uzip: [(1, 2, 3), (4, 5, 6)]
print "the uzip part of z1:%s\nthe uzip part of z2:%s"%(str(uzip[0]),str(uzip[1]))
the uzip part of z1:(1, 2, 3)
the uzip part of z2:(4, 5, 6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*args和**kw
args仅仅只是用在函数定义的时候用来表示位置参数应该存储在变量args里面。Python允许我们制定一些参数并且通过args捕获其他所有剩余的未被捕捉的位置。当调用一个函数的时候,一个用标志的变量意思是变量里面的内容需要被提取出来然后当做位置参数被使用。
def add(x, y):
return x + y
list_ = [1,2]
add(list_[0], list_[1]) # 3
add(*list_) # 3
1
2
3
4
5
6
*args要么是表示调用方法大的时候额外的参数可以从一个可迭代列表中取得,要么就是定义方法的时候标志这个方法能够接受任意的位置参数。接下来提到的,kw代表着键值对的字典,也就是说,你不用一个个字典用key来取value了
dict_ = {'x': 1, 'y': 2, 'z':3}
def bar(x, y, z):
return x + y + z
bar(**dict_) # 6
bar(dict_['x'],dict_['y'],dict_['z']) # 6
1
2
3
4
5
6
内建函数 itertools优雅的迭代器
方法很多,就先介绍笔试题碰到的permutations
permutations(p[,r]);返回p中任意取r个元素做排列的元组的迭代器
如:permutations(‘abc’, 2) # 从’abcd’中挑选两个元素,比如ab, bc, … 将所有结果排序,返回为新的循环器。
注意,上面的组合分顺序,即ab, ba都返回。
combinations(‘abc’, 2) # 从’abcd’中挑选两个元素,比如ab, bc, … 将所有结果排序,返回为新的循环器。
注意,上面的组合不分顺序,即ab, ba的话,只返回一个ab。
再来个实际点的算法的一个例子,虽然毫无算法结构可言
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba
itertools,内建库的用法
参考:http://blog.csdn.net/neweastsun/article/details/51965226
import itertools
def Permutation(ss):
# write code here
if not ss:
return []
return sorted(list(set(map(lambda x:''.join(x), itertools.permutations(ss)))))
Permutation('abc')