接Day02的语句与表达式
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
python中可以迭代的对象,因为是它是迭代器,实现原理是_next_()方法,可以访问下一个元素
在Python中如果一个对象有__iter__( )方法或__getitem__( )方法,则称这个对象是可迭代的(Iterable);其中__iter__( )方法的作用是让对象可以用for … in循环遍历,getitem( )方法是让对象可以通过“实例名[index]”的方式访问实例中的元素。换句话说,两个条件只要满足一条,就可以说对象是可迭代的。显然列表List、元组Tuple、字典Dictionary、字符串String等数据类型都是可迭代的。当然因为Python的“鸭子类型”,我们自定义的类中只要实现了__iter__( )方法或__getitem__( )方法,也是可迭代的。
f = open(‘data.txt’,encoding=‘utf-8’)
在Python中如果一个对象有__iter__( )方法和__next__( )方法,则称这个对象是迭代器(Iterator);其中__iter__( )方法是让对象可以用for … in循环遍历,next( )方法是让对象可以通过next(实例名)访问下一个元素。注意:这两个方法必须同时具备,才能称之为迭代器。列表List、元组Tuple、字典Dictionary、字符串String等数据类型虽然是可迭代的,但都不是迭代器,因为他们都没有next( )方法。
可迭代对象不会占用太多内存,例如一个教大的文本文件
我们现在有两种方法进行逐行读取
第一种是readlines()方法
#
f = open('data.txt',encoding='utf-8')
print(type(f))
x=f.readlines()
print(type(x))
可以看到第一个返回的是一个文件对象(迭代器对象),第二个返回的是一个列表对象。这时候我们需要进行逐行读取,之前采用readlines()的方法读取,创建了一个list对象存储这些行,但list的创建相比于迭代器的读取next方法会消耗更多的内存,因为list对象相当于一次性存储了所要读取对象的所有值
for a in x:
print(a,end='')
print('\n')
f = open('data.txt',encoding='utf-8')
while True:
try:
print(f.__next__(),end='')
except StopIteration:
print('读取迭代完成')
break
两种逐行读取的方法
#############
xxxxxxxxxxxxxxxx
zzzzzzzzzz
哈哈哈哈
#############
xxxxxxxxxxxxxxxx
zzzzzzzzzz
哈哈哈哈读取迭代完成
for。。。。
推导…
map…
迭代器对象
已经实现迭代方法
可迭代对象
需要额外使用iter()->_iter()_方法生成迭代器
list1 = [1,2,3,5]
next(list1)
TypeError: 'list' object is not an iterator
list1 = [1,2,3,4,5]
list2 =iter(list1)
print(next(list2))
print(next(list2))
print(next(list2))
print(next(list2))
print(next(list2))
1
2
3
4
5
iter(A) is A
zip(),map(),range()
def double_number(x):
return x * 2
l=[1,2,3,4,5]
result = list(map(double_number,l))
print(result)
[2, 4, 6, 8, 10]
一般格式
定义:
def 函数名(参数1,参数2,.....):
....#代码逻辑
调用:
函数名(实参)
s1= 'abcgfjdhsgf'
s2= 'azsxdc'
def intersect(seq1,seq2):#传递两个参数
res = []#申明一个空的列表res
for x in seq1:#遍历第一个参数
if x in seq2:#遍历第二个参数,看上一层遍历的值是否在第二个参数中
res.append(x)#拼接列表
return res
l = intersect(s1,s2)
print(l)
['a', 'c', 'd', 's']
与C,java基本相同
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。
num = 1
def fun1():
global num # 使用关键字申明
print(num)
num = 123
print(num)
fun1()
print(num)
1
123
123
内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:
import builtins
dir(builtins)
print(type(dir(builtins)))
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
def changelist(list1):
"修改传入的列表"
list1.append([1,2,3])
print("list1 = ",list1)
listst = [10,25,36]
changelist(listst)
print("listst = ",listst)
changelist(listst.copy())
print("listst = ",listst)
list1 = [10, 25, 36, [1, 2, 3]]
listst = [10, 25, 36, [1, 2, 3]]
#传递对象值改变
listst = [10, 25, 36, [1, 2, 3]]
#可以通过copy方法 传副本或者新建一个变量等于它传进去,这样做不影响原来的对象及引用
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
语法
lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
举例
sum = lambda arg1,arg2:arg1+arg2
print("相加后的值为:",sum(1,50))
相加后的值为: 51
不声明变量调用隐式函数最后的name不是内部变量,是参数
函数内参数匹配支持 关键字匹配,位置匹配
关键字参数允许参数调用时与声明的不一致,因为Python 解释器能够用参数名匹配参数值。
#可写函数说明
def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
名字: runoob
年龄: 50
def XXX(*参数1):{
}
参数前面加个*号 代表可以接收任意数量的参数
接收元组参数
def (name,age,*arg,**args)
**
参数以字典的形式导入
def printinfo(arg1,**vardict):
print('输出:')
print(arg1)
for k,v in vardict.items():
print(k,v)
print(type(vardict))
printinfo('个人信息:',name='Tom',age=13,salary=300.6)
输出:
个人信息:
name Tom
age 13
salary 300.6
现阶段理解 将函数作为变量传递,不直接调用,而是采用间接调用,方便不同场景下使用
-----------------------------------------分割线--------------------------------------------------------------------------
#练习题 1-5所有的平方值
result = [ x**2 for x in range(1,6)]
for i in result:
print(i)
//整除符号
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值
def xxxx():
return #返回None
return xx #返回某个参数