前言
正式开始疯狂学习状态了,把考试考完之后就把刷leetcode再次提上日程!然后幸福生活还有8天!可以说是苦日子里的小甘甜
python推导式
推导式comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 共有三种推导,在Python2和3中都有支持:
- 列表(list)推导式
- 字典(dict)推导式
- 集合(set)推导式
列表推导式
variable = [out_exp_res for out_exp in input_list out_exp ]
out_exp_res: 列表生成元素表达式,可以是有返回值的函数。
for out_exp in input_list: 迭代input_list将out_exp传入out_exp_res表达式中。
out_exp: 条件表达式,筛选数据
例子:
#打印30以内的数字,所有能被3整除的整数的平方
result = [i**2 for i in range(1,31) if i % 3 == 0]
print(result)
[9, 36, 81, 144, 225, 324, 441, 576, 729, 900]
#找到嵌套列表中名字含有2个'e'的所有名字
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eve']]
result = [i for names_a in names for i in names_a if i.lower().count('e') == 2]
print(result)
['Jefferson', 'Wesley', 'Steven', 'Jennifer', 'Eve']
三元运算与列表推导式(if else 放在循环语句前)
q = [x if x%3==0 else -x for x in range(1,101)]
print(q)
字典推导式
字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。
基本格式:variable = {out_key:out_value for out_key,out_value in input_ldict if out_exp == 2}
. out_key: 返回字典结果的key
. out_value: 返回字典结果的value
. for out_key,out_value in input_list:迭代input_list将out_exp传入out_exp_res表达式中。
. if out_exp == 2:根据条件过滤哪些值可以。
例子:
合并大小写对应的value值,将k统一成小写
result3 = {x.lower():q4.get(x.upper(),0)+q4.get(x.lower(),0) for x in q4.keys()}
print(result3)
{'b': 9, 'a': 5, 'c': 3}
集合推导式
它们跟列表推导式也是类似的。 唯一的区别在于它使用大括号{},而且列表推导式自带去重功能
l = [-1, 1 ,2 ,1]
li = {i*i for i in l}
print(li)
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
可迭代对象
凡是可以返回一个迭代器的对象都可称之为可迭代对象。
- 如何确认一个对象是不是可迭代对象:
可迭代对象实现了iter方法,该方法返回一个迭代器对象 使用Iterable判断
from collections.abc import Iterator
a = range(100)
if isinstance(a, Iterator):print("yes")
else:
print("no")
可迭代对象有哪些
• 容器都是可迭代对象
- 容器(container)
- 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not
in关键字判断元素是否包含在容器中。
通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如
迭代器和生成器对象) - 在Python中,常见的容器对象有str,list, deque, tuple , …
• 此外还有更多的对象同样也是可迭代对象,比如处于打开状态的files,sockets等等。
• 凡是可以返回一个迭代器的对象都可称之为可迭代对象
什么是迭代器
迭代器是有状态的,可以被next()调用,函数调用并不断返回下一个值的对象称为迭代器(Iterator)。
任何实现了iter()和next()都是迭代器
. __iter__():返回迭代器自身
. __next__():返回容器中的下一个值
. 如果容器中没有更多元素了,则抛出StopIteration异常
. (for循环取数据遇到StopIteration时,会退出循环)
. 所有的Iterable均可以通过内置函数iter()来转变为Iterator。
可迭代对象和迭代器转换
iter()函数:
a = [1,2,3]
a_iter = iter(a)
生成无限序列
from itertools import count,cycle
counter = count(start=1, step=2)
print(counter, type(counter))
print(next(counter))
print(next(counter))
print(next(counter))
count(1, 2) <class 'itertools.count'>
1
3
5
从有序序列中生成无限序列
from itertools import count,cycle
counter = count(start=1, step=2)
print(counter, type(counter))
weeks = cycle([1,2,3,4,5,6,7])
print(weeks , type(weeks))
for i in range(21):
print(next(weeks))
1
2
3
4
5
6
7
1
2
迭代器的好处
迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候
就处于休眠状态等待下一次调用。
生成器
生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,
不过这种迭代器更加优雅。它不需要手动编写iter()和next()方法,只需要一个
yiled关键字。
- 生成器一定是迭代器(反之不成立)
- 因此任何生成器也是以一种懒加载的模式生成值
yield关键字
包含yield表达式的函数是特殊的函数,叫做生成器函数(generator function),被调用时将
返回一个迭代器(iterator),调用时可以使用next或send(msg)
- 一个生成器中可以有多个yield
一旦遇到yield,就会保存当前状态,然后返回yield后面的值
a = [x+2 for x in range(10)]
print(a)
def func2():yield 0 yield 1 yield 2 yield 3 yield 4 yield 5 raise StopIteration yield 6 yield 7
a = func2()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
for i in a:print(i)
生成器例子
斐波拉基序列
from itertools import islice
def fib():
a = 1
b = 1
while True:
yield a
a ,b= b,a + b
print(list(islice(fib(),0,10)))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
生成器 fib() 的执行过程
• 当执行f=fib()返回的是一个生成器对象,此时函数体中的代码并不会执行,而是首先
返回一个 iterable 对象!
• 只有显示或隐示地调用next的时候才会真正执行函数里面的代码
• 执行到语句 yield b 时,fab() 函数会返回yield后面(右边)的值,并记住当前执行的状
态
• 下次调用next时,程序流会回到 yield b 的下一条语句继续执行
• 看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过
yield 返回当前的迭代值。
• 由此可以看出,生成器通过关键字 yield 不断的将迭代器返回到内存进行处理,而不
会一次性的将对象全部放入内存,从而节省内存空间。
send数据
除了可以使用 next() 方法来获取下一个生成的值,用户还可以使用 send() 方法将一个
新的或者是被修改的值返回给生成器。除此之外,还可以使用 close() 方法来随时退出
生成器
def counter(staet_at = 0):
count = staet_at
while True:
val = (yield count)
if val is not None:
count = val
else :
count += 1
count = counter(5)
print(next(count))
print(next(count))
print(next(count))
print(count.send(9))
print(next(count))
count.close()
print(next(count))
迭代器与生成器的区别
先说迭代器,对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数,iter()是python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIteration异常,通知for语句循环结束。
生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)