@myles
2018-06-09T15:08:06.000000Z
字数 2845
阅读 847
老男孩基础
三元表达式又称条件表达式,这些表达式基于真(true)/假(false)的条件判断,在Python 2.4以上才有了三元操作。
#如果条件为真,返回真 否则返回假
condition_is_true if condition else condition_is_false
n = 10
print("%s:条件为真执行"%n) if n>5 else print("%s: 条件为假执行"%n)
10:条件为真执行
列表生成式就是一个用来生成列表的特定语法形式的表达式。
[exp x for var in iterable]
运行过程
(1)迭代iterable 中的每一个元素
(2)每次迭代的元素都复制给var变量,然后在通过exp表达式得到一个新的值
(3)最后把所有exp运算的值都以一个列表的形式返回
实际举例
>>> [x+2 for x in range(10)]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[exp if if_exp else else_exp for var in iterable]
运行过程
(1)迭代iterable中每一个元素
(2)每次迭代的元素都复制给var变量,然后在通过if三运运算表达式得到一个新的值
(3)最后把所有exp运算的值都以一个列表的形式返回
实际举例
[x if x<5 else x*2 for x in range(10)]
[0, 1, 2, 3, 4, 10, 12, 14, 16, 18]
[exp for var_A in iterable_A for var_B in iterable_B]
L = []
for iter_var_A in iterable_A:
for iter_var_B in iterable_B:
L.append(exp)
>>> [(x,y) for x in range(5) for y in 'ABCDE']
[(0, 'A'), (0, 'B'), (0, 'C'), (0, 'D'), (0, 'E'), (1, 'A'), (1, 'B'), (1, 'C'), (1, 'D'), (1, 'E'), (2, 'A'), (2, 'B'), (2, 'C'), (2, 'D'), (2, 'E'), (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'), (3, 'E'), (4, 'A'), (4, 'B'), (4, 'C'), (4, 'D'), (4, 'E')]
实际举例比较感受然的不同
>>> L = ['Myles', 10, 'Jhon']
# map 函数实现
>>> list(map(lambda x:x.lower() if isinstance(x,str) else x,L))
['myles', 10, 'jhon']
# 列表生成器实现
# >>> [x.lower() if isinstance(x,str) else x for x in L]
['myles', 10, 'jhon']
# 列表推导式实现
>>> [x.lower() for x in L if isinstance(x,str)]
['myles', 'jhon']
# map() 结合 filter()实现
list(map(lambda x:x.lower(),filter(lambda x:isinstance(x,str),L)))
['myles', 'jhon']
通过以上的比较,可以很明显的了解到"列表生成器"使用起来更加方便简单。
从名字上来看,生成器应该是用来生成数据的。
按照某种算法不断生成新的数据,直到满足某一个指定的条件结束。
构造生成器的两种方式:
(1)使用类似列表生成式的方式生成 (2*n + 1 for n in range(3, 11))
(2)使用包含yield的函数来生成
如果计算过程比较简单,可以直接把列表生成式改成generator;但是,如果计算过程比较复杂,就只能通过包含yield的函数来构造generator。
g = (x**2+1 for x in range(1,10))
g
<generator object <genexpr> at 0x000001E8CA1E4830>
for x in g:
print(x)
2
5
10
17
26
37
50
65
82
# 方法2:使用包含yield函数构造生成器
def num(x,y):
for n in range(x,y):
yield n**2+1
g = num(1,10)
for x in g:
print(x)
2
5
10
17
26
37
50
65
82
生成器的执行过程
在执行过程中,遇到yield关键字就会中断执行,下次调用则继续从上次中断的位置继续执行。
生成器的特性
(1) 只有在调用时才会生成相应的数据
(2) 只记录当前的位置
(3) 只能next,不能prev
g = (x**2 for x in range(10))
next(g)
0
next(g)
1
next(g)
4
next(g)
9
g = (x**2 for x in range(10,20))
for x in g:
print(x)
100
121
144
169
196
225
256
289
324
361
>>> def fib(max):
n,a,b = 0,0,1
while n<max:
a,b = b,a+b
print("before yield b")
yield b #(1)生成一个"generator";(2)冻结程序执行;(3)将结果返回到函数之外
print('b')
n = n + 1
return 'Done'
>>> f = fib(5) # 返回一个生成器
>>> f
<generator object fib at 0x000001E8CA1E4AF0>
>>> next(f) # 第一次执行,执行到yield就停止了,并将结果返回到函数之外
before yield b
1
>>> next(f) # 第二次执行,执行"print('b'),然后执行"print("before yield b")",最后执行到"yield"就停止了,并返回结果。
b # 执行"print('b')
before yield b # 执行"print("before yield b")"
2 # 最后执行到"yield"就停止了,并返回结果
>>> next(f)
b
before yield b
3
>>> next(f)
b
before yield b
5