and
代码中可以使用and来控制函数的执行
def testPrint()
print("hello")
return True
False and testPrint()
<<<False # 表明testPrint()并没有执行
True and testPrint()
<<<hello
<<<True # 表明testPrint()执行
因此我们可以通过variable and function()的形式,通过变量来控制函数的执行与否
assert
使用方法上
assert condition
等同于
if not condition:
raise AssertionError()
还可以以这样的形式写:
assert condition "comment"
如下:
assert False, "comment"
Traceback (most recent call last):
File "<input>", line 1, in <module>
AssertionError: comment
assert True, “comment” 不输出同时也无Traceback
字符串格式化
在python用tuple或字典将多个值传递给模板,每个值对应一个格式符
元祖形式如下:
print("I'm %s. I'm %d year old" % ('Vamei', 99))
print("I'm %s." % ('Vamei',))
字典形式如下:
print("I'm %(name)s. I'm %(age)d year old" % {'name':'Vamei', 'age':99})
此处注意括号后面仍要添加s、d等格式符
格式符列表:
%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)
%% 字符"%"
进一步的格式控制实现:
%[(name)][flags][width].[precision]typecode
(name)为命名
flags可以有+,-,’ ‘或0。+表示右对齐。-表示左对齐。’ '为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填充。
width表示显示宽度
precision表示小数点后精度
print("%+10x" % 10)
print("%04d" % 5)
print("%6.3f" % 2.3)
上面的width, precision为两个整数。我们可以利用*,来动态代入这两个量,如
print("%.*f" % (4, 1.2))
Python实际上用4来替换*。所以实际的模板为"%.4f"。
yield
本部分解释来源:https://blog.csdn.net/mieleizhi0522/article/details/82142856
初步认识可以认为yield等同于return,但同时带有yield的函数会变成一个生成器(generator)(生成器是一个返回迭代器的函数)
实例:
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))
<<<starting...
<<<4
<<<********************
<<<res: None
<<<4
解释:
1.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)
2.直到调用next方法,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环
3.程序遇到yield关键字,然后把yield想想成return,return了一个4之后,程序停止,并没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,
4.程序执行print("*"20),输出20个
5.又开始执行下面的print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,
6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 出4,然后程序停止,print函数输出的4就是这次return出的4.
实例
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(g.send(7))
<<<starting...
<<<4
<<<********************
<<<res: 7
<<<4
解释
先大致说一下send函数的概念:此时你应该注意到上面那个的紫色的字,还有上面那个res的值为什么是None,这个变成了7,到底为什么,这是因为,send是发送一个参数给res的,因为上面讲到,return的时候,并没有把4赋值给res,下次执行的时候只好继续执行赋值操作,只好赋值为None了,而如果用send的话,开始执行的时候,先接着上一次(return 4之后)执行,先把7赋值给了res,然后执行next的作用,遇见下一回的yield,return出结果后结束。
5.程序执行g.send(7),程序会从yield关键字那一行继续向下运行,send会把7这个值赋值给res变量
6.由于send方法中包含next()方法,所以程序会继续向下运行执行print方法,然后再次进入while循环
7.程序执行再次遇到yield关键字,yield会返回后面的值后,程序再次暂停,直到再次调用next方法或send方法。
生成器的优势
为什么用这个生成器,是因为如果用List的话,会占用更大的空间,比如说取0,1,2,3,4,5,6…1000
你可能会这样:
for n in range(1000):
a=n
这个时候range(1000)就默认生成一个含有1000个数的list了,所以很占内存。
这个时候你可以用刚才的yield组合成生成器进行实现,也可以用xrange(1000)这个生成器实现
yield组合:
def foo(num):
print("starting...")
while num<10:
num=num+1
yield num
for n in foo(0):
print(n)
输出:
starting...
1
2
3
4
5
6
7
8
9
10
xrange(1000):
for n in xrange(1000):
a=n
其中要注意的是python3时已经没有xrange()了,在python3中,range()就是xrange()了,你可以在python3中查看range()的类型,它已经是个<class ‘range’>了,而不是一个list了,毕竟这个是需要优化的。
Dict取值
对于最基本的python使用者可能也已经掌握了很多获取字典中值得方法,但是在实际使用过程中会有一种情况是为了避免出现线上trace情况发生,在通过键取值时不采用dict[key]等方法而是优先选用dict.get(key, default=None)和dict.setdefault(key, default=None)来进行键值查询和添加新键值对