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

python--生成器、三元表达式、列表解析、生成器表达式

2017-06-19 17:07 661 查看

补充:

在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
func_dic={}
def make_dic(key):
def deco(func):
func_dic[key] = func
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
return res
return wrapper
return deco

@make_dic('index') # @deco #f1=deco(f1)
def f1():
print('from f1')

@make_dic('home')
def f2():
print('from f2')

@make_dic('auth')
def f3():
print('from f3')

print(func_dic)
while True:
cmd = input('>>: ').strip()
if cmd in func_dic:
func_dic[cmd]()
结果:
>>: index
from f1
>>: home
from f2
>>: auth
from f3

列表解析

先来两个栗子:

s = 'hello'

l = []
for i in s:
res = i.upper()
l.append(res)

print(l)
结果:
['H', 'E', 'L', 'L', 'O']
l = [1, 2, 3, 4]
l_new = []
for i in l:
res = i**2
l_new.append(res)
print(l_new)
结果:
[1, 4, 9, 16]

接下来就是我们的列表解析:

s = 'hello'
res = [i.upper() for i in s]
print(res)
结果:
['H', 'E', 'L', 'L', 'O']
l = [1, 31, 73, 84, 57, 22]
res = [i for i in l if i > 50]
print(res)
结果:
[73, 84, 57]

列表解析的形式:

for i in obj1:
if 条件1:
for i in obj2:
if 条件2:
for i in obj3:
if 条件3:
...

生成器表达式

g = (i for i in range(100000000000000000000000000000000000000000000000000))

print(g)
print(next(g)) #next(g) == g.__next__()
print(next(g)) #next(g) == g.__next__()
print(next(g)) #next(g) == g.__next__()
print(next(g)) #next(g) == g.__next__()
print(next(g)) #next(g) == g.__next__()
结果:
<generator object <genexpr> at 0x0000000002734990>
0
1
2
3
4

注意:和[i for i in range(1000000000000000000000000000000000000000000)]的区别,有兴趣可以尝试运行此命令。。

len('hello') #'hello'.__len__()

print(len('hello'))
print('hello'.__len__())
结果:
5
5

注意:

相似的原理:iter(g)     #g.__iter__()

三元表达式

x = 2
y = 3

if x > y:
print(x)
else:
print(y)

res = 'aaaaa' if x > y else 'bbbbbbb'

print(res)
结果:
3
bbbbbbb
def max2(x, y):
# if x > y:
#     return x
# else:
#     return y

return x if x > y else y

print(max2(1, 2))
结果:
2

生成器函数

函数体内包含有yield关键字,该函数执行的结果是生成器

def foo():
print('first------>')
yield 1
print('second----->')
yield 2
print('third----->')
yield 3
print('fourth----->')

g = foo()
print(g)

from collections import Iterator
print(isinstance(g, Iterator))
结果:
<generator object foo at 0x0000000001E14990>
True

所以我们得到的结果:生成器就是迭代器

def foo():
print('first------>')
yield 1
print('second----->')
yield 2
print('third----->')
yield 3
print('fourth----->')

g = foo()

print(g.__next__())
print(g.__next__())
print(g.__next__())
# print(g.__next__())  #StopInteration
结果:
first------>
1
second----->
2
third----->
3
def foo():
print('first------>')
yield 1
print('second----->')
yield 2
print('third----->')
yield 3
print('fourth----->')

g = foo()

for i in g: #obj=g.__iter__() #obj.__next__()
print(i)
结果:
first------>
1
second----->
2
third----->
3
fourth----->

上两例对比,我们可以看到for 自动捕捉到了StopInteration

总结:

'''
yield的功能:
    1.与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次值
    2.为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器
    3.遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的
'''

def countdown(n):
print('starting countdown')

while n > 0:
yield n
n -= 1
print('stop countdown')
g = countdown(5)
print(g)
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
# print(g.__next__()) #StopInteration
结果:
<generator object countdown at 0x0000000001DF4990>
starting countdown
5
4
3
2
1

同样地,用for可以捕捉StopInteration。

def countdown(n):
print('starting countdown')

while n > 0:
yield n
n -= 1
print('stop countdown')
g = countdown(5)
print(g)

for i in g:
print(i)
结果:
<generator object countdown at 0x0000000002144990>
starting countdown
5
4
3
2
1
stop countdown

应用:tail -f a.txt

import time
def tail(filepath, encoding='utf-8'):
with open(filepath, encoding=encoding) as f:
f.seek(0, 2)
while True:
# f.seek(0, 2) #不行
line = f.readline()
if line:
# print(line,end='')
yield line
else:
time.sleep(0.5)

g = tail('a.txt')
print(g)
print(g.__next__())
结果:
<generator object tail at 0x0000000001E04AF0>
1111111111

或者可以应用for:

for i in g:
     print(i)

应用:tail -f a.txt | grep 'error'



import time
def tail(filepath, encoding='utf-8'):
with open(filepath, encoding=encoding) as f:
f.seek(0, 2)
while True:
# f.seek(0, 2) #不行
line = f.readline()
if line:
# print(line,end='')
yield line
else:
time.sleep(0.5)

def grep(lines, pattern):
for line in lines:
if pattern in line:
# print(line)
yield line
tail_g = tail('a.txt')
print(tail_g)

grep_g = grep(tail_g, 'error')

print(grep_g)

print(grep_g.__next__())
结果:
<generator object tail at 0x0000000001E24A98>
<generator object grep at 0x0000000001E24AF0>
qweerror

或者可以应用for:

for i in grep_g:

    print(i)

作业:
1 编写 tail -f a.txt |grep 'error' |grep '404'命令,周一默写
2 文件a.txt内容
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3

要求使用列表解析,从文件a.txt中取出每一行,做成下述格式
[{‘name’:'apple','price':10,'count':3},{...},{...},...]

3 格式与2一样,但只保留价格大于1000的商品信息

4 周末大作业(见图):
只实现作业要求的查询功能
增加,删除,修改功能为选做题

答案:
# 1 编写 tail -f a.txt |grep 'error' |grep '404'命令,周一默写

import time
file_path = r'C:\Users\Administrator\PycharmProjects\untitled\a.txt'
def tail(file_path):
with open(file_path, encoding='utf-8') as f:
f.seek(0, 2)
while True:
line = f.readline()
if line:
yield line
else:
time.sleep(0.5)

def grep(lines, pattern):
for line in lines:
if pattern in line:
yield line

g1 = tail('a.txt')
g2 = grep(g1, 'error')
g3 = grep(g2, '404')
for i in g3:
print(i)

# 2 文件a.txt内容
# apple 10 3
# tesla 100000 1
# mac 3000 2
# lenovo 30000 3
# chicken 10 3
#
# 要求使用列表解析,从文件a.txt中取出每一行,做成下述格式
# [{‘name’:'apple','price':10,'count':3},{...},{...},...]
#
# print([{'name': i.split()[0], 'price': i.split()[1], 'count': i.split()[2]} for i in
#        open('a.txt')])
print([{'name': i.strip().split()[0], 'price': i.strip().split()[1], 'count': i.strip().split()[2]} for i in
open('a.txt')])

# 3 格式与2一样,但只保留价格大于1000的商品信息
#
print([{'name': i.strip().split()[0], 'price': i.strip().split()[1], 'count': i.strip().split()[2]}for i in
open('a.txt') if i.strip().split()[1] > '1000'])

# 4 周末大作业(见图):
#     只实现作业要求的查询功能
#     # 增加,删除,修改功能为选做题

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: