Python教程

Python基础 - 06推导式及生成器

本文主要是介绍Python基础 - 06推导式及生成器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Python基础 - 06推导式及生成器

一、列表推导式 

格式:  [表达式 for 变量 in 旧列表]  [表达式 for 变量 in 旧列表 if 条件] 

names = ['tom', 'lily', 'abc', 'Hello', 'Jack', 'lucy']
result1 = [name for name in names if len(name) > 3]
print(result1)                     # ['lily', 'Hello', 'Jack', 'lucy']

result2 = [name.capitalize() for name in names if len(name) <= 3]
print(result2)                     # ['Tom', 'Abc']

# 将1-100之间被3整除的数字组成一个列表
result3 = [num for num in range(1, 101) if num % 3 == 0]
print(result3)

result4 = [num for num in range(1, 101) if num % 3 == 0 and num % 5 == 0]
print(result4)

# 0-5 偶数  0-10 奇数   (0,1) (0,3) ... (0,9) (2,1) (2,3) ...
result5 = [(x, y) for x in range(5) if x % 2 == 0 for y in range(10) if y % 2 != 0]
print(result5)

  

employee1 = {'name': 'zhangsan', 'salary': 4300}
employee2 = {'name': 'lisi', 'salary': 5500}
emp = [employee1, employee2]
n = [employee['salary'] + 200 if employee['salary'] > 4500 else employee['salary'] + 500 for employee in emp]
print(n)  # [4800, 5700]

  

二、字典推导式、集合推导式

list1 = [1, 2, 3, 1, 5, 3, 2, 6, 8, 9, 8, 8, 9]
set1 = {x - 1 for x in list1 if x > 5}       # 类似列表推导式,没有重复元素
print(set1)                                  # {8, 5, 7}

dict1 = {'k1': 'v1', 'k2': 'v2'}
newdict = {value: key for key, value in dict1.items()}
print(newdict)                               # {'v1': 'k1', 'v2': 'k2'}

  

三、生成器

使用列表推导式生成列表,但受到内存限制,容量有限。 创建一个100万元素的列表,仅仅需要访问前面几个元素,造成空间浪费。

边循环边计算的机制,称为生成器, generator

next(generator): 每次调用都会产生一个新的元素,如果元素都产生完毕,再次调用会产生异常。

生成器方法: g.__next__()    g.send(value) 

3.1 定义生成器

list2 = [x * 3 for x in range(10)]
print(type(list2))                 # <class 'list'>

g = (x * 3 for x in range(5))
print(type(g))                     # <class 'generator'>
print(g)                           # <generator object <genexpr> at 0x000000DC2790DF90>
print(g.__next__())                # 0
print(g.__next__())                # 3
print(g.__next__())                # 6
print(next(g))                     # 9
print(next(g))                     # 12
#print(next(g))                    # StopIteration

3.2 使用try...except 结构读取生成器元素; 读取读取的方式 next(g) 或 g.__next__()  

while True:
    try:
        e = next(g)
        print(e)
    except:
        print('没有元素啦')
        break
print('测试结束')
'''
0
3
6
9
12
没有元素啦
测试结束
'''

3.3 定义生成器方式: 函数   

# 定义生成器方式二: 函数
# 只要函数中出现yield关键字,则函数不再是函数,变成生成器了。
def func6():
    n = 0
    while True:
        n += 1
        # print(n)
        yield n      # 效果等同于  return n + 暂停

g = func6()

print(g)         # <generator object func6 at 0x0000008356E8DF20>
print(next(g))   # 1
print(next(g))   # 2

  

使用生成器实现斐波那契数列:

def fib(length):
    a, b = 0, 1
    n = 0
    while n < length:
        yield b
        a, b = b, a + b
        n += 1

g = fib(8)
print(next(g))  # 1
print(next(g))  # 1
print(next(g))  # 2
print(next(g))  # 3
print(next(g))  # 5
print(next(g))  # 8
print(next(g))  # 13
print(next(g))  # 21

 

def fib(length):
    a, b = 0, 1
    n = 0
    while n < length:
        print(b)
        a, b = b, a + b
        n += 1

fib(8)  # 也能实现输出 1 1 2 3 5 8 13 21

3.4 生成器带return语句 

def fib(length):
    a, b = 0, 1
    n = 0
    while n < length:
        yield b
        a, b = b, a + b
        n += 1

    return 'abc'

g = fib(8)
print(next(g))  # 1
print(next(g))  # 1
print(next(g))  # 2
print(next(g))  # 3
print(next(g))  # 5
print(next(g))  # 8
print(next(g))  # 13
print(next(g))  # 21
print(next(g))  # StopIteration: abc ;没有 return时,报错StopIteration

3.5 send方法: 向生成器中传值 

def gen():
    i = 0
    while i < 5:
        temp = yield i
        print('temp: ', temp)
        i += 1
    return '没有数据了'

g = gen()
print(g.__next__())  # 0
print(g.__next__())  # temp:  None  \n  1
print(g.__next__())  # temp:  None  \n  2

n1 = g.send('呵呵')
print('n1: ', n1)    # temp:  呵呵   \n  n1:  3
n2 = g.send('哈哈')
print('n2: ', n2)    # temp:  哈哈   \n  n2:  4
n3 = g.send(None)    # temp:  None  \n  StopIteration: 没有数据了,  取值时没有了报错,赋值成功
print('n3: ', n3)    # 这个没有执行

 直接往生成器非None传值报错

g = gen()

# print(g.__next__())  
# print(g.__next__())  
# print(g.__next__())  
n1 = g.send('呵呵')
# 报错:
# TypeError: can't send non-None value to a just-started generator

 

g = gen()

print(g.send(None))     #  改成   n = g.send(None) 也可以
n1 = g.send('呵呵')
print('n1: ', n1)   
'''
0
temp:  呵呵
n1:  1
'''

  

def gen1():
    i = 0
    while i < 5:
        temp = yield i
        print('temp: ', temp)
        for i in range(temp):
            print('------->', i)
        print('**************')
        i += 1
    return '没有数据了'

g1 = gen1()
print(g1.send(None))
n1 = g1.send(3)
print('n1:',n1)
'''
0
temp:  3
-------> 0
-------> 1
-------> 2
************** 
n1: 3
'''

n2 = g1.send(4)
print('n2:', n2)
'''
temp:  4
-------> 0
-------> 1
-------> 2
-------> 3
**************
n2: 4
'''

  

def task1(n):
    for i in range(n):
        print('正在搬第{}块砖'.format(i+1))
        yield None

def task2(n):
    for i in range(n):
        print('正在听第{}首歌'.format(i+1))
        yield None

g1 = task1(3)
g2 = task2(2)


while True:
    g1.__next__()
    g2.__next__()

'''
正在搬第1块砖
正在听第1首歌
正在搬第2块砖
正在听第2首歌
正在搬第3块砖
Traceback (most recent call last):
  File "E:\PythonLearn\pythonBase\02door2\08-generator-03.py", line 23, in <module>
    g2.__next__()
StopIteration
'''

 

处理异常:  

while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        pass

 

3.6 可迭代与迭代器  

# 可迭代的对象   1. 生成器            2. 元祖 列表 集合 字典 字符串
# 如何判断一个对象是否可迭代

from collections import Iterable

list1 = [1,2,46,5,3]
result = isinstance(list1, Iterable)
print(result) # True

result = isinstance('abc', Iterable)
print(result) # True

result = isinstance(100, Iterable)
print(result) # False

  

迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有元素都被访问完结束。迭代器只能往前不会后退。

# 可以被next()函数调用并返回下一个值的对象称为迭代器:Iterable。
# 可迭代的 不一定就是迭代器。
# 生成器是可迭代的,是迭代器。 list是可迭代的,但不是迭代器。
list1 = iter(list1)
print(next(list1)) # 1
print(next(list1)) # 2

  

 

这篇关于Python基础 - 06推导式及生成器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!