[Python]推导式与生成器


推导式可方便生成数据集合,而生成器可返回一个可迭代的对象。

推导式

推导式表达式是一种可从一个序列构建另外一个新数据序列的数据处理方式,Python中有三种推导式:列表推导式、字典推导式和集合推导式。

列表推导式

列表推导式用于快速生成一个列表:

[表达式 for 变量 in 可迭代对象] 

[表达式 for 变量 in 可迭代对象 if 条件]

如生成100内偶数列表:
numbers = [i for i in range(100) if i%2==0]

字典推导式

字典推导式用于快速生成一个字典:

{键:值表达式 for 变量 in 可迭代对象} 

{键:值表达式 for 变量 in 可迭代对象 if 条件}

如快速对换字典的键与值:

numMap = {1:'one', 2:'two', 3:'three'}

numRev = {v:k for k,v in numMap.items()}

集合推导式

集合推导式与列表推导式类似,只是外面使用大括号:

{表达式 for 变量 in 可迭代对象} 

{表达式 for 变量 in 可迭代对象 if 条件}

如获取字符串中字符数:

s = 'abcdeffsdfsaf'

ch = {x for x in s}
print(len(ch))

生成器

一边循环一边计算的机制,称为生成器(generator):

  • 生成器能迭代的关键是其有__next__方法:
    • 通过next(g),获取下一个元素;当没有更多元素时,会抛出StopIteration异常;
    • 通过for x in g循环来依次获取生成器中元素;
  • 带有yield的函数不再是普通函数,而是一个生成器:
    • yield类似return返回一个值,但会记住此位置,下次迭代时从下一条语句继续执行;
    • .send()next()类似,但会传递一个值,此值作为yield表达式整体结果返回。

生成器表达式

生成器与推导式类似,但生成器表达式占更少的内存,因为:

  • 生成器表达式中的元素是按需逐个生成的;
  • 推导式是一次将所有元素生成,放到内存中。
(表达式 for 变量 in 可迭代对象)

(表达式 for 变量 in 可迭代对象 if 条件)

也可把生成器转换为其他集合(tuple或list)来获取其全部元素:

gen = (x**2 for x in range(5))
print(tuple(gen))

函数生成器

通过yield可把普通函数变成生成器:

def genNum(count=10):
    for n in range(count):
        yield n

num = genNum(5)
for i in num:
    print(i)
send

要使send生效(send的参数为yield的返回值),需要修改yield语句:

  • 获取返回值,然后重设yield的变量;
  • 在调用send前,需要要已调用过next(保证已挂在yield语句处);
 def genNum(count=10):
     i = 0
     while i < count:
         v = (yield i)
         if v:
             i = v
         else:
             i += 1

 num = genNum()
 print(next(num)) # 0
 print(num.send(3)) # 跳过1、2,返回3
 for i in num:  # 从4开始
     print(i)

可迭代对象

能够逐一迭代返回元素的对象即为可迭代对象,包括:

  • 所有序列类型:str、list、tuple、range;
  • 非序列集合:set、dict、文件对象(open返回的);
  • 实现了__iter__()方法的任意对象;
  • 实现了__getitem__()方法的任意对象;

迭代器

定义了__iter__()(必须返回一个迭代器)方法的对象,就实现了迭代协议;即为一个迭代器:

  • 所有可迭代对象,都可通过iter()方法转换为迭代器:如iter('abcd')
  • 迭代器使用next()进行迭代操作;*
class GenNumbers:
    def __init__(self, count):
        self.count = count

    def __iter__(self):
        self.n = 1
        return self

    def __next__(self):
        if self.n <= self.count:
            x = self.n
            self.n += 1
            return x
        else:
            raise StopIteration

gen = GenNumbers(10)
for i in gen:
    print(i)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值