Python 基础知识
1、明确定义:容器(container)、可迭代对象(iterable)、迭代器(iterator)、生成器(generator)
- 容器 : 把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取。这是由于可迭代对象使容器可被迭代。但不是所有容器均可迭代,例如Bloom filter,因为它没把元素存储在容器中,而是通过一个散列函数映射成一个值保存在数组中。
可以用in, not in关键字判断元素是否包含在容器中,以字典为例:
d = {1: 'foo', 2: 'bar', 3: 'qux'}
assert 1 in d
assert 'foo' not in d # 'foo' 不是dict中的元素
# 注:assert fasle 会报错 只有逻辑为True才会什么都不返回
在Python中常见的容器对象 [高亮的是我知道的] |
list[列表], deque |
set{集合}, frozensets |
dict{字典}, defaultdict, OrderedDict, Counter |
tuple(元组), namedtuple |
str”字符串“ |
- 可迭代对象:指可被循环的对象,或者说,凡是可以返回一个迭代器的对象都可称之为可迭代对象。并不是具体的数据类型。
- 迭代器:对 Collection 进行迭代的类,是访问可迭代对象的工具,是用iter(obj)函数返回的对象(实例),是用next(it)函数获取可迭代对象的数据。
#~ 举例解释蓝色字体
iterator = iter(iterable obj) # 从可迭代对象中返回一个迭代器。注:iterable obj:可迭代对象
next(iterator)# 从迭代器iterator中获取下一条记录,若无法获取,则触发stoptrerator异常
补充介绍Collection:是一个基本的集合接口,Collction的三个子类:
list | Set | Queue |
1. 有序的集合,可控制元素插入的顺序,也可根据下标直接访问操作元素。 | 1.通常Set是无序的,不保证元素的插入顺序,部分实现除外(LinkedHashSet)。 | 1.专为进行处理前保存元素而设计的集合。 |
2.通常允许包含重复的元素,包括重复的null元素。 | 2.不允许包含重复的元素,底层通过Map实现。 | 2.通常不允许插入null元素 |
- 生成器:是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法),无需再手动实现。生成器在迭代的过程中可以改变当前迭代值,而修改普通迭代器的当前迭代值往往会发生异常,影响程序的执行。生成器通过生成器函数产生,生成器函数用常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。使用生成器可以很方便的支持迭代器协议。[注意:yield与return的不同是,前者不会在返回后释放,而是在下一次迭代时,生成器从yield下一句执行,直到遇到下个yield。 ](举例在最后)
2、可迭代对象与迭代器实现及区别:
- 定义可迭代对象:必须实现__ iter __方法;
- 定义迭代器:因迭代器也是可迭代对象,故迭代器也要实现__ iter __方法,在此基础上还要实现next方法
具体实现:
- __ iter __():返回的是当前对象的迭代器类的实例
- 在可迭代对象中的实现:返回该可迭代对象的迭代器类的实例。
- 在迭代器类的实现:直接返回self(即自己本身),表示自身即是自己的迭代器。
- next():返回迭代的每一步,实现该方法时注意要最后超出边界要抛出StopIteration异常。即用except捕获,然后不作处理。
def gen(n):
i=0
while True:
if i<=n:
yield i
i+=1
else:
raise StopIteration
iter_gen=iter(gen(10))
try:
while True:
print(next(iter_gen))
except StopIteration:
pass
下面是可迭代对象与迭代器的举例:
class MyList(object): # 定义可迭代对象类
def __init__(self, num):
self.data = num # 上边界
def __iter__(self):
return MyListIterator(self.data) # 返回该可迭代对象的迭代器类的实例
class MyListIterator(object): # 定义迭代器类,其是MyList可迭代对象的迭代器类
def __init__(self, data):
self.data = data # 上边界
self.now = 0 # 当前迭代值,初始为0
def __iter__(self):
return self # 返回该对象的迭代器类的实例;因为自己就是迭代器,所以返回self
def next(self): # 迭代器类必须实现的方法
while self.now < self.data:
self.now += 1
return self.now - 1 # 返回当前迭代值
raise StopIteration # 超出上边界,抛出异常
my_list = MyList(5) # 得到一个可迭代对象
print type(my_list) # 返回该对象的类型
my_list_iter = iter(my_list) # 可迭代器实例 = iter(可迭代对象)
print type(my_list_iter)
for i in my_list: # 迭代
print i
iter函数的主要用法:iter(collection)用于返回collection对象的迭代器实例。collection上面由说到,因其为各种可迭代对象的集合,故这里将其理解为可迭代对象。
3、生成器举例
def myList(num): # 定义生成器
now = 0 # 当前迭代值,初始为0
while now < num:
val = (yield now) # 返回当前迭代值,并接受可能的send发送值;yield在下面会解释
now = now + 1 if val is None else val # val为None,迭代值自增1,否则重新设定当前迭代值为val
my_list = myList(5) # 得到一个生成器对象
print my_list.next() # 返回当前迭代值
print my_list.next()
my_list.send(3) # 重新设定当前的迭代值
print my_list.next()
print dir(my_list) # 返回该对象所拥有的方法名,可以看到__iter__与next在其中
结果: