首页 > 代码库 > note on python

note on python

iterator

Behind the scenes, the for statement calls iter() on the container object. The function returns an iterator object that defines the method __next__() which accesses elements in the container one at a time. When there are no more elements, __next__() raises a StopIteration exception which tells the for loop to terminate.You can call the __next__() method using the next() built-in function

可以自己实现一个类的for loop:

class A:
	class it:
		def __init__(s,a):
			s.a=a
			s.l=len(s.a.l)+len(s.a.l2)
			s.i=0
		def __next__(s):
			if s.i==s.l:
				raise StopIteration
			a=0
			if s.i<len(s.a.l):
				a= s.a.l[s.i]
			else:
				a= s.a.l2[s.i-len(s.a.l)]
			s.i=s.i+1
			return a
	def __init__(s):
		s.l=[1,2,4,5]
		s.l2=[4,3,2,0]
	def __iter__(s):
		return A.it(s)

>>> a=A()
>>> [i for i in a]
[1, 2, 4, 5, 4, 3, 2, 0]

generator

Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the yield statement whenever they want to return data. Each time next() is called on it, the generator resumes where it left off (it remembers all the data values and which statement was last executed).

def gen(a):
	for i in a.l:
		yield i
	for i in a.l2:
		yield i

>>>for i in gen(a):
	print (i,end=‘,‘)

1,2,4,5,4,3,2,0,

generator expression

def gen():
	return ((i,j)for i in range(10)for j in range(9))
或:
for a in((i,j)for i in range(10)for j in range(9)):
	print (a)

for a in (...generator exp...)是在每次call next()时才生成a,而for a in [...list comprehension...]是提前就生成一个列表,据说前者效率更高

class and instance variables

我的理解,对于mutable变量,对象复制类的变量的一个“指针“:

>>> class A:
	li=[]
	def add(s,x):
		s.li.append(x)

		
>>> a=A()
>>> a.add(3)
>>> a.li
[3]
>>> b=A()
>>> b.add(4)
>>> b.li#b.li像是A.li的一个引用,已经被a.li修改过
[3, 4]
正确的做法:
>>> class A:
	def __init__(s):
		s.li=[]#每次创建对象都生成一个对象自己的列表
	def add(s,x):
		s.li.append(x)

		
>>> a=A()
>>> a.add(3)
>>> a.li
[3]
>>> b=A()
>>> b.add(4)
>>> b.li
[4]

而对于immutable 变量则类似于按值传递(尽管python中没有这些概念),不会有这个问题



note on python