Python学习笔记03

1. 迭代与迭代协议

接Day02的语句与表达式

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()。

字符串,列表或元组对象都可用于创建迭代器:
python中可以迭代的对象,因为是它是迭代器,实现原理是_next_()方法,可以访问下一个元素

1.1 可迭代

在Python中如果一个对象有__iter__( )方法或__getitem__( )方法,则称这个对象是可迭代的(Iterable);其中__iter__( )方法的作用是让对象可以用for … in循环遍历,getitem( )方法是让对象可以通过“实例名[index]”的方式访问实例中的元素。换句话说,两个条件只要满足一条,就可以说对象是可迭代的。显然列表List、元组Tuple、字典Dictionary、字符串String等数据类型都是可迭代的。当然因为Python的“鸭子类型”,我们自定义的类中只要实现了__iter__( )方法或__getitem__( )方法,也是可迭代的。

f = open(‘data.txt’,encoding=‘utf-8’)

1.2 迭代器

在Python中如果一个对象有__iter__( )方法和__next__( )方法,则称这个对象是迭代器(Iterator);其中__iter__( )方法是让对象可以用for … in循环遍历,next( )方法是让对象可以通过next(实例名)访问下一个元素。注意:这两个方法必须同时具备,才能称之为迭代器。列表List、元组Tuple、字典Dictionary、字符串String等数据类型虽然是可迭代的,但都不是迭代器,因为他们都没有next( )方法。

1.3 好处

可迭代对象不会占用太多内存,例如一个教大的文本文件
我们现在有两种方法进行逐行读取
第一种是readlines()方法

#
f = open('data.txt',encoding='utf-8')
print(type(f))
x=f.readlines()
print(type(x))
<class '_io.TextIOWrapper'>
<class 'list'>

可以看到第一个返回的是一个文件对象(迭代器对象),第二个返回的是一个列表对象。这时候我们需要进行逐行读取,之前采用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
哈哈哈哈读取迭代完成
1.4 迭代工具

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

1.5 全局函数next()
1.6 内置可迭代对象

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]

2.函数定义及参数

2.1 函数定义
注意:定义函数会将python自带的同名参数覆盖

一般格式
定义:

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']
2.2 变量的作用域

与C,java基本相同

  • L (Local) 局部作用域
  • E (Enclosing) 闭包函数外的函数中
  • G (Global) 全局作用域
  • B (Built-in) 内置作用域(内置函数所在模块的范围)

在这里插入图片描述

2.2.1 global 和 nonlocal关键字

当内部作用域想修改外部作用域的变量时,就要用到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

内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:

import builtins
dir(builtins)
print(type(dir(builtins)))

<class 'list'>
2.3 可更改(mutable)与不可更改(immutable)对象

在 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方法 传副本或者新建一个变量等于它传进去,这样做不影响原来的对象及引用

2.4 函数与Lambda表达式

python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

2.4.1 语法

语法
lambda 函数的语法只包含一个语句,如下:

lambda [arg1 [,arg2,.....argn]]:expression

举例

sum = lambda  arg1,arg2:arg1+arg2
print("相加后的值为:",sum(1,50))
相加后的值为: 51

不声明变量调用隐式函数最后的name不是内部变量,是参数
在这里插入图片描述

2.5 参数匹配

函数内参数匹配支持 关键字匹配,位置匹配
关键字参数允许参数调用时与声明的不一致,因为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
<class 'dict'>

委托机制

现阶段理解 将函数作为变量传递,不直接调用,而是采用间接调用,方便不同场景下使用

-----------------------------------------分割线--------------------------------------------------------------------------

练习题

#练习题 1-5所有的平方值
result = [ x**2 for x in range(1,6)]
for i in result:
    print(i)

方法与函数

//整除符号

return语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值

def xxxx():
return #返回None
return xx #返回某个参数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值