Python迭代器与生成器
迭代器是访问集合元素的一种方式,可以记住遍历的位置的对象
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问结束,迭代器只能向前不能向后
迭代器有两个基本的方法:iter(),next()
字符串,列表,或元组对象都可以创建迭代器
list = ['lin','hu','qwe','22']
i = iter(list) #创建迭代器对象
print(next(i)) #输出迭代器的的洗一个元素,输出:lin
print(next(i)) #输出:hu
#迭代器对象可以使用for语句进行遍历
tuple = ('zx','yu','2310','12')
j = iter(tuple) #创建迭代器
for x in j:
print(x,end=' ')
创建一个迭代器
把一个类作为一个迭代器使用,需要在类中实现iter(),next()两个方法
python中的构造函数为init,它会在对象初始化的时候执行
iter()方法返回一个特殊的迭代器对象,这个迭代器对象实现了next()方法并通过StopIteration异常标识迭代的完成
next()方法会返回下一个迭代器对象
创建一个返回数字的迭代器,初始值为1,逐步递增1 (目前学到这里,这个代码没看懂,后续再看)
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
StopIteration异常用于标识迭代的完成,防止无限循环的产生,在next()方法中我们可以在执行完成指定的循环次数的时候触发StopIteration异常来结束迭代。
生成器
在python中使用yield的函数被称为生成器
跟普通的函数不同,生成器是一个返回迭代器的函数,只用于迭代操作,即生成器就是一个迭代器,在调用生成器运行的过程中,每次遇到yield函数会暂停并保存当前所有的运行信息返回yield的值,并在下一次执行next()方法时从当前位置继续运行,调用一个生成器函数,返回一个迭代器的值,例子:斐波那契数列
学完函数我们在回来看
Python函数
函数是组织好的,可以重复的使用,用来实现单一或者相关联功能的代码段
函数能提高应用的模块性和代码的重复利用率
定义一个函数
函数代码块以def关键字开头,后接函数标识符名称和圆括号()
任何传入的参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
函数内容以冒号起始,并且缩进
return【表达式】结束函数,选择性返回一个值给调用方,不带表达式的return相当于返回None
定义函数的语法
def 函数名():
函数体
#定义一个简单的函数来输出hello word
#def hello():
# print("hello word")
#hello()
#函数中带上变量参数
def area(width ,height):
return width * height
h = 12
w = 13
print('height=', h, "wdith=", w, 'area=', area(h, w))
函数的调用
定义一个函数:给了函数一个名称,指定函数包含的参数,和代码块结构
这个函数的基本结构完成后,可以通过另一个函数调用执行
#实例调用printme()函数
#定义函数
def printme(str): #打印传入的字符串
print(str)
return
#调用函数
printme("唯一是一个小宝宝")
printme("唯一小宝宝今年一岁了")
参数传递
在python中类型属于变量,变量是没有类型的
a = [1,2,3,4,5]
a = 'string'
[1,2,3,4,5]是list类型,’string‘是string类型而a是没有变量的它仅仅是一个对象的引用(一个指针),可以指向list类型对象,也可以指向string类型
可更改(mutable)与不可更改(immutable)对象
string,numbers,tuple对象shi不可更改的,而list,dict对象则是可以更改的
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
"""#传不可变对象实例
def changint(a):
a = 1
b = 10 #int对象10 指向b,在传递给changeint函数时,按传值的方式复制了变量b,a和b都指向同一个int对象
#在 a=1 时,则新生成一个 int 值对象 1,并让 a 指向它
changint(b)
print(b)"""
#传可变对象实例
def changeme(mylist):
mylist.append([1,34,5])
print("函数内取值",mylist)
return
#调用changeme函数
mylist =[12,345,56]
changeme(mylist)
print("函数外取值:",mylist)
参数:可使用的正式参数,必须参数,关键字参数,默认参数,不定长参数
必须参数 以正确的顺序传入函数,调用时的数量必须和声明时的一样
关键字参数:关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值,
默认函数:调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值
def printinfo(name,age=13):
print("姓名为:",name)
print('年龄为:',age)
return
printinfo(name='lin',age=12)
printinfo(name='hu')
Python中的匿名函数用lambda来创建匿名函数
所谓匿名,即是不使用def标准化的函数的定义的方式定义一个函数
lambda只是一个表达式,函数体比def简单的多|
lambda的主体是一个表达式而不是一个代码块,仅仅能在lambda表达式中封装有限的逻辑进去
lambda拥有自己的命名空间,不能访问自己列表外或者全局变量中的参数
lambda 函数的语法只包含一个语句,如下:
1 |
|
sum = lambda a,b,:a*b
#调用sum函数
print("sum的值为:",sum(10,20))
return[表达式],不带参数的return都返回None
def sum(a,b):
c=a+b
print("c的值为:",c)
return c
c = sum(10,3)
Python3数据结构
列表
将列表当做堆栈使用
列表方法将列表很方便的作为一个堆栈来使用,堆栈作为特殊的数据结构,最先进入的元素最后一个被释放(后进先出),使用append()方法可以把一个元素添加到堆栈顶,用不指定索引的pop()方法可以把一个元素从堆栈顶释放出来
stack = [1,2,3,4,5]
stack.append(6)
stack.append(7)
print(stack)
stack.pop()
print(stack)
将列表当作队列使用
在队列里第一加入的元素,第一个取出来;但是拿列表用作这样的目的效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")
queue.append("Graham")
print(queue)
queue.popleft()
print(queue)
列表推导式
嵌套列表解析
del语句
使用del语句是通过索引来删除列表中的元素的而不是通过值来删除
元组和序列
t = 12,'yuyu','ah'
print(t[0])
print(t)
u = t,('222e',2)
print(u) #(12, 'yuyu', 'ah')
#((12, 'yuyu', 'ah'), ('222e', 2))
字典
构造函数 dict() 直接从键值对元组列表中构建字典。如果有固定的模式,列表推导式指定特定的键值对:
1 2 |
|
遍历
在遍历字典时,键,值可以用item()同时遍历出来
dict={'lin':18,'hu':19,'秦王':'嬴政'}
for i,j in dict.items():
print(i,j)
#同时遍历两个或更多的序列,可以使用 zip() 组合:
questions= ["name","age","corlor"]
answers= ['lin','18岁','red']
for x,y in zip(questions,answers):
print("你的%s"%(x),"它是%s"%(y))