目录
1. iterable 可迭代对象:
2. iterator迭代器:
3. generator function 生成器
4. 通过推导式实现Generator【生成器】
5. 推导式
关系:Generator是特殊的Iterator【迭代器】,同时他们都是可迭代对象,list,tuple,set,dict也是可迭代对象
实现了 __iter__(self) 方法的对象,在该方法中返回一个迭代器或者实现了next(python2)或者 __next__(self) (python3)的对象
常见可迭代对象:tuple,list,set,dict
from collections import Iterable, Iterator
print(isinstance(dict(), Iterable)) # True
print(isinstance(dict(), Iterator)) # False
# list, set, tuple 类似
示例:
class Test:
def __init__(self):
# 实现next方法的对象,该对象能通过next()方法调用获取下一个值,从而实现迭代
self.__max = 10
self.__cur_num = 0
def __next__(self): # python3 实现
return self.next()
def next(self): # python2 中实现
if self.__cur_num < self.__max:
tmp, self.__cur_num = self.__cur_num, self.__cur_num + 1
return tmp
else: # 用于终止循环
raise StopIteration()
class MyIterable(object):
"""iterable, 可迭代对象,实现了__iter__方法"""
def __iter__(self):
return Test()
from collections import Iterable, Iterator
isinstance(MyIterable(), Iterable) # True
isinstance(MyIterable(), Iterator) # False
isinstance(Test(), Iterable) # False
isinstance(Test(), Iterator) # False
同时实现 __iter__() 和 __next__ 方法的对象【python2中要实现next()方法 】
class MyIterator(object):
"""iterable, 可迭代对象,实现了__iter__方法"""
def __init__(self):
# 实现next方法的对象,该对象能通过next()方法调用获取下一个值,从而实现迭代
self.__max = 10
self.__cur_num = 0
def __iter__(self):
# 返回对象本身,因为自身实现了 __next__ 方法
return self
def __next__(self): # python3 实现
return self.next()
def next(self): # python2 中实现
if self.__cur_num < self.__max:
tmp, self.__cur_num = self.__cur_num, self.__cur_num + 1
return tmp
else: # 用于终止循环
raise StopIteration()
from collections import Iterable, Iterator
isinstance(MyIterable(), Iterable) # True
isinstance(MyIterable(), Iterator) # True
生成器函数:具有iterator行为,即一种特殊类型的迭代器
实现 yield关键字 语句的函数(function)为生成器函数,yield是返回值的意思,不同于return,return返回值的同时函数退出运行,而yield不会退当循环继续时他会继续执行后面语句,知道完成迭代
def my_iter(n=10):
cur = 0
while True:
if cur < n:
yield cur
cur += 1
else:
break
m = my_iter() # 返回一个迭代器同时也是生成器,my_iter为生成器函数
from collections import Iterable, Iterator
isinstance(my_iter(), Iterator) # 返回 True
from collections import Generator # 只有python3中有Generator对象
isinstance(my_iter(), Generator) # 返回True
# 示例, 可以先看推导式介绍,然后在看此内容
string = 'Furthermore, this is a pattern that we will use over and over for many similar constructs. Imagine writing all that just to get an iterator. '
my_iter = (i for i in string.strip().split(' '))
# 检测
from collections import Iterable, Iterator
isinstance(my_iter, Iterator) # 返回 True
from collections import Generator # 只有python3中有Generator对象
isinstance(my_iter, Generator) # 返回True
# 详解:
数据准备:
iterable = [1, 2, 3, 4, 5] # 示例
1. 列表推导式
基本格式:
m_list = [i for i in iterable if i >= 0]
解析:
[变量处理[可以不做处理,可以是有返回值的函数,或者表达式] for 变量 in 可迭代对象 if 条件[过滤掉不符合条件的]] # if 部分可以没有
m = [i ** 2 for i in iterable if i >= o]
def func(x):
return x * x
m = [func(i) for i in iterable]
m = [(lambda x: x * x)(i) for i in iterable] # 使用 lambda函数【匿名函数】
2. 集合推导式
基本格式
m = {i for i in iterable if i > 0} # i 必须为可哈希的对象
于列表推导式区别:
(1) 使用大括号`{}`
(2) i 元素必须可哈希
其余同列表推导式
3. 字典推导式
基本格式
m = {k: v for k, v in iterable} # 其中也可以加 if 条件
m = {k: True for k in iterable} # 其中最大括号部分k, v 可以写表达式或者函数,同列表推导式
注:
没有元组推导式,因为小括号的为Generator【生成器】
可以通过tuple(i for i in [1, 2, 3])该方式生成
4. 高级
推导式用可以有多个for循环
m = [i * j for i in iter1 for j in iter2] # 类似于笛卡尔积结果
笛卡尔积: https://baike.baidu.com/item/%E7%AC%9B%E5%8D%A1%E5%B0%94%E4%B9%98%E7%A7%AF/6323173?fr=aladdin
如果i也是可迭代的,则第二个循环对i循环
例如:
iter1 = [[1, 2, 3], [4, 5]]
m = [j for i in iter1 for j in i]
我就写到这里了,推导式中还可以嵌套实现复杂推导式,可以自己研究啊,下面放一个综合应用的例子:
# 自己实现的解析GTF文件的类【生物信息分析中使用】
# 涉及到的技术,python2和python3兼容
# 上下文管理
# 列表推导式,字典推导式, 迭代器
class GtfFile(object):
def __init__(self, file_path):
self.__file_handler = None
self.__file_path = file_path
def __init_handler(self):
self.__file_handler = open(self.__file_path)
seek = 0
while True:
line = self.__file_handler.readline()
if not line.startswith('#') and line != '\n':
self.__file_handler.seek(seek)
break
seek = self.__file_handler.tell()
def __enter__(self):
if self.__file_handler is None:
self.__init_handler()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.__file_handler.close()
def __iter__(self):
if self.__file_handler is None:
self.__init_handler()
return self
def __next__(self):
"""
python3 iterator iter method
:return:
"""
if self.__file_handler is None:
self.__init_handler()
line = self.__file_handler.readline()
if not line:
raise StopIteration
line_splits = line.strip().split('\t')
line_splits[3] = int(line_splits[3])
line_splits[4] = int(line_splits[4])
line_splits[8] = {
k.strip(): v.strip(' "')
for k, v in (
item.strip().split(' ', 1) for item in line_splits[8].strip('; ').split(';')
)
}
return line_splits, line
def next(self):
"""
python2 iterator iter method
:return:
"""
return self.__next__()
# 使用示例
file = r'your file path'
with GtfFile(file) as gtf_handler:
# line_list: 为解析后行内容, line: 为原行字符串[ 没做任何处理 ]
for line_list, line in gtf_handler:
attr_dict = line_list[8]
gene_id = attr_dict.get('gene_id')
pass