本文内容为基于一些文章进行的个人总结。水平有限,仅供参考。
本文参考:
python: deque vs list performance comparison
Build a Basic Python Iterator
Python yield 使用浅析
Python迭代器和生成器
学习python最先接触到的迭代是for in
迭代
for i in [1, 2, 'a', 'b']:
print(i)
生成数组时我们还经常用到range()
函数
for i in range(1, 100):
print(i)
range()
函数会返回一个创建好的数组,但是当数组元素较多时会占用内存。
这时可用xrange()
函数,xrange()
函数返回的是一个生成器(generator)实例,只有在调用时才进行计算,而不是一次性计算出来。
python3 没有
xrange
,python3中的range
即为python2中的xrange
for i in xrange(1, 100):
print(i)
所以要生成一个首项为1,公差为3的10项等差数列,利用range()
可写为:
l = [1 + 3 * i for i in range(11)]
考虑到代码的复用、性能优化,可改写为:
def generate_list(a_1, d, n):
try:
a_1 = float(a_1)
d = float(d)
n = int(n)
except ValueError:
return []
l = []
for i in xrange(n):
l.append(a_1 + d * i)
return l
# 这里两种方法都可以,数组较多时上面的会快一些,大家可以测试下
# return [a_1 + d * i for i in xrange(n)]
l = generate_list(1, 3, 10)
在python中,具有__iter__
方法的对象均可迭代。
当需要对数组操作时可以使用python内置库collections
中的deque
类,deque
是“double_end_queue”的缩写,译为“双端队列”,发音同“deck”,可从两端对数组进行操作(插入、删除)。
在算法复杂度上deque
为O(1),而list
为O(n),即对于n个相同元素的数组而言,如果deque
对象的执行次数为常数C,那么list
对象执行次数为Cn。所以deque
的性能要优于list
。
from collections import deque
# list操作
a = range(10000)
a.append(1) # 从后面追加元素 1
a.insert(0, 1) # 从前面追加元素 1
a.pop() # 从后面删除元素(删除最后一个元素)
a.pop(0) # 从前面删除元素(删除第一个元素)
# deque操作
b = deque(a)
b.append(1) # 从后面追加元素 1
b.appendleft(1) # 从前面追加元素 1
b.pop() # 从后面删除元素(删除最后一个元素)
a.popleft() # 从前面删除元素(删除第一个元素)
于是上面的例子可以改为:
def generate_list(a_1, d, n):
try:
a_1 = float(a_1)
d = float(d)
n = int(n)
except ValueError:
return []
l = deque()
for i in xrange(n):
l.append(a_1 + d * i)
return l
# 如果想返回list需要转一下
# return list(l)
l = generate_list(1, 3, 10)
用yield
可以将一个函数变为生成器,即在迭代遍历时才对进行生成计算。上面的例子可以改为:
def generate_list(a_1, d, n):
try:
a_1 = float(a_1)
d = float(d)
n = int(n)
except ValueError:
return []
for i in xrange(n):
yield a_1 + d * i
l = generate_list(1, 3, 10)
可以这样理解:yield
记录函数运行的状态,遍历l
时,会返回yield
作用的值,并停止,下一次调用时会继续执行yield
后面的代码,直到再次遇到yield
。