Python学习第五天

1、Pyhton中的迭代

       面试问题:python中哪些对象可以使用for循环?或者说可以遍历?   答:可d迭代的对象,或者是实现了迭代器协议的对象都是可以被循环遍历的!  在对象的内部有一个方法,__next__()   前后双下划线,可以迭代的对象、能够使用for遍历的,这个对象肯定实现了迭代协议,实现了迭代协议的特点是内部实现了__next__() 方法,  调用__next__() 方法的时候是一样一样的读取!  再全局函数中也有一个next() 方法 ,切记 他是一个全局函数! 

  可迭代对象和列表之间的差异:  
        可迭代对象在内存中只会占用一小片的内存空间! 然后读完这块空间中的数据以后,会调用__next__()方法,在所占内存空间不变的情况下,想要读取下一个就要移指针到下一个数据上! 但是列表会在内存中占用大量的存储空间,如果文件过大的话! 就会对内存造成很大的压力。

     上图中第一个图是内存! 方框是迭代器的内存!  ! 右图是一个列表! 如果去读取的话!就需要跟list登长的内存将数据加载进来。

 

迭代工具的原理:迭代工具有for     有推导  有map  。 有的类型虽然也能使用for!但是其内部并没有实现__next()__方法,是在使用for循环的时候帮他他添加的一个! 原理是这样的
      for遍历出来的迭代器分为,迭代器对象和可迭代对象:: 两者的区别是迭代器对象已经内部实现了__next()__方法,也可以使用全局函数next(),就比如文本文件,就是一个迭代器对象,可以直接使用__next()__对象还有全局next()函数。 
      而可迭代对象就不一样了,可迭代对象中并没有自己实现迭代器! 需要我们手动实现,手动实现的方法就是调用   iter(想要被迭代的对象)。这样这个方法就具备了__next__ 和next()方法。就比如列表就是一个可迭代对象。
      怎么样可以知道类型是否为迭代类型呢!? iter(类型1)  is  类型1   。 使用一个iter方法查看。

 

函数的定义与参数:

   函数的作用:最大化代码重用 、 最小化代码冗余 、 过程分解。
   定义格式:def 函数名(参数1,参数2,.......) :      换行缩进  写方法体 ,或者写在一行也行。
    调用: 函数名(实际参数)。

 重点掌握:变量的作用域是(local)   外侧的变量是全局的!! 如果我们想要使用全局的变量! 需要在方法体中声明一个 global 关键字,来告诉函数,我要使用的变量是全局的变量!
     其实还有一个范围!是内置范围,Built—in 这个范围,这个作用域比Global还要高! built-in这个范围就是你把python内置的函数给另外起名了!
      还有一种范围:python2中没有,python3中有,叫做封装(Enclousure):使用的场景是函数套函数的时候能够使用到
    例子:

def func():
    x = 100
    def nested():
        x = 99
        print(x)
    nested()
    print(x)

那么问题来了! 如果我想要让nested这个函数里面的x也使用func里面的函数应该怎么做呢!?

def func():
    x = 100
    def nested():
        nonlocal x
        x = 99
        print(x)
    nested()
    print(x)

只需要加上一个nolocal这个关键字就行!

 这四个的顺序是:local --->enclousure---->global----->built-in   从最低层到最高层的一个顺序。

参数的讲解:先来一个例子:
 

def change_number(x):
    x += 10
x = 5

print('x = {}'.format(x))
change_number(x)
print('x = {}'.format(x))

输出的是:x = 5  x = 5 : 为什么这样呢?
         因为,默认的情况下!我们的变量或者实际的值向我们的函数传递的时候,需要看看是什么类型!看看是否课改变的!上面的代码中传入的x =5 ,5是一个整型,是不可以被改变的!
        不可改变的类型在传值的时候呢! 会先做出来一个副本出来。然后才会传递到函数中去。所以不管函数改不改变该值!都对原值没有任何影响!
        如果是传递的是列表。是可以改变的类型! 那样就会改变了:
 

def chang_list(l):
    l[1] = 99
    l[2] = 20

l = [1,2,3,4,5]
print("原始的列表式是",format(l))
chang_list(l)
print("调用后的列表是",l)

 这样就会改变了!如果我们不想让它进行改变的话!那么我们就在change_list(l.copy())  在copy出来一个副本即可。这样函数无论进行什么操作,都不会影响原始值。

记住一句话:不可变类型:int型、浮点型、字符串型、tuple型、都是不可变型!都是传递副本,可变类型都是传递的地址引用!函数类操作会影响该原始值!

 

 

 

 

 

      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值