迭代(for循环)

混江龙づ霸主 提交于 2019-12-06 05:47:24

例子

#for x in [1,2,3]: #列表
#   print(x)

#for x in (1,2,3): #元组
#   print(x)

文件本身也是个可迭代的对象:

创建一个new file:data.txt在里面写入

优品课堂学编程 好心情www.codeclassroom.comwww.youpinketang.comwww.uke.cc

 

再在main.py里写入 

f = open('data.txt',encoding='utf8')

for line in f: #for line在刚才的f里
    print(line, end=' ') #遍历出来结果的行,结尾用空格结束

1、迭代协议:_next_()

_next_()不是暴露出来给客户调用,可以获取下一个元素,就是一行一行读 next:所占内存空间不变的情况,如果想获得数据,移到下一项,移动指针用的

pyhon console里写入

f = open('data.txt',encoding='utf8')f.__next__()

'优品课堂\n'

 

典型支持迭代协议对象

>>> f = open('data.txt',encoding='utf8')
>>> next(f)
'优品课堂\n'
>>> next(f)
'学编程 好心情\n'
>>> next(f)
'www.codeclassroom.com\n'

 

>>>f = open ('data.txt',encoding='utf8')
>>> for x in f.readlines(): #返回一个列表,把所有行找到放到list里,不写ReadLines好,数据大不支持还是用for...open更好不占太多内存
...     print(x)
...     
优品课堂

学编程 好心情

www.codeclassroom.com

www.youpinketang.com

www.uke.cc

 调用全局函数直接写next

 

列表:可迭代的对象

>>> urls = ['youpinketang.com','uke.cc','codeclassroom.com']
>>> for url in urls:
...     print(url)
...     
youpinketang.com
uke.cc
codeclassroom.com

2、迭代工具for...推导...map...

(1)迭代对象

(2)可迭代对象

f = open('data.txt',encoding='utf8')
f.__next__()
'优品课堂\n'
for i in [1,2,3]:
    print(i)
    
1
2
3
f = open('data.txt',encoding='utf8')
for line in f:
    print(line)
    
优品课堂
学编程 好心情
www.codeclassroom.com
www.youpinketang.com
www.uke.cc

结果一样差别在于f本身具备next方法,但是列表没有

 

iter(f) is f#iter全局函数包起来f判断一下f是不是应用了迭代器功能,返回true证明使用next方法
True
>>> f = open('data.txt',encoding='utf8')
>>> iter(f) is f #iter全局函数包起来f判断一下f是不是应用了迭代器功能,返回true证明使用next方法
True
True
>>> f.__next__()
'优品课堂\n'
>>> next(f)#把f传进去本质同上
'学编程 好心情\n'

列表:不具有上面的功能,套一个进去就可以用了

>>> iter(urls) is urls #判断列表是否本身有迭代器,发现不是
False
>>> i = iter(urls)#所以没有next,用for实现,或迭代器等于urls把刚才的传进去
>>> i.__next__()
'youpinketang.com'

 >>> next(i)
 'uke.cc'

 

 手动迭代,返回一个列表中所有元素,要平方值

法1使用for 次啰嗦

>>> l = [1,2,3]
>>> res = [] #做个空列表
>>> for x in l:
...     res.append(x**2) #装列表的最加x平方项
...     
>>> res
[1, 4, 9]

法2手动实现不用for 最啰嗦

>>> i = iter(l) #iter全局的方法把列表加进去
>>> while True:
...     try:
... 
...         x = res.append(next(i) ** 2)  # i里取个值放入res里,追加
... 
...     except StopIteration:  # 捕获异常跳出循环
... 
...         break
>>> res
[1, 4, 9, 1, 4, 9]

法3实际开发,手推导 推荐使用

result = [x**2 for x in l]
result
[1, 4, 9]

 字典表

用for找元素

>>> emp = {'name':'Tom','age':20,'job':'dev','salary':8000.00}
>>> for k,v in emp.items():
...     
...     print(k,v)
...     
name Tom
age 20
job dev
salary 8000.0
>>> emp.items()#看items类型,发现不是列表虽然很像
dict_items([('name', 'Tom'), ('age', 20), ('job', 'dev'), ('salary', 8000.0)])
>>> for k in emp:
...     
...     print(k)
...     
name
age
job
salary
>>> emp.keys()#看所有键
dict_keys(['name', 'age', 'job', 'salary'])
>>> emp.values()#也不是列表
dict_values(['Tom', 20, 'dev', 8000.0])

 

不用for找挨个元素

>>> keys = emp.keys()#先声明一个keys,看类型
>>> keys
dict_keys(['name', 'age', 'job', 'salary'])
>>> iter(keys) is keys#看是keys本身吗false不包含next方法
False
>>> i = iter(keys)
>>> i.__next__()
'name'
>>> i.__next__()
'age'
>>> i.__next__()
'job'
>>> i.__next__()
'salary'

可迭代都可放入推导表达式内,推导的基础:前半截是返回的结果,中间是过滤的过程,后面if是过滤的条件:res4 = [url for url in urls if url.endswith('.com')]#过滤,地址包含.com

>>> l = [1,2,3,4,5]
>>> res1 = [x for x in l]#在l遍历,每个元素放稳定变量x,取x本身放入x,[]表示返回列表
>>> type(res1)
<class 'list'>
>>> res1
[1, 2, 3, 4, 5]
>>> res2 = [x+10 for x in l] #列表找单个数把数字每个加10
>>> res2
[11, 12, 13, 14, 15]
>>> urls = ['youpinketang.com','uke.cc','codeclassroom.com']
>>> res3 = [url.upper() for url in urls]#变大写
>>> res3
['YOUPINKETANG.COM', 'UKE.CC', 'CODECLASSROOM.COM']
>>> res4 = [url for url in urls if url.endswith('.com')]#过滤,地址包含.com
>>> res4
['youpinketang.com', 'codeclassroom.com']

 法2 繁琐

>>> res5 = []
>>> for x in urls:
...     
...     if x.endswith('.com'):
...         
...         res5.append(x)
...         
>>> res5
['youpinketang.com', 'codeclassroom.com']

 3、内置可迭代对象 range()生成序列,它不是列表虽然和列表很像

>>> range(50)
range(0, 50)
>>> r = range(1,20)#1-20序列
>>> type(r)
<class 'range'>
>>> for x in range(1,11):
...     print(x)
...     
1
2
3
4
5
6
7
8
9
10
>>> result = [x**2 for x in range(1,6)]#1-5平方值算出
>>> result
[1, 4, 9, 16, 25]

可迭代对象 :1自己实现next方法 2 没有

range用法:

测试

>>> r = range(1,6)
>>> iter(r) is r #r生成的迭代器是它本身吗
False

不允许

>>> r = range(1,6)
>>> iter(r) is r
False
>>> i = iter(r) #r自动生成next方法
>>> i.__next__()
1
>>> next(i)#也可用全局的方法
2

 zip用法:将连个集合合成一个,本质也是可迭代对象

>>> result = zip(['x','y','z'],[1,2,3]) #xyz调用123
>>> result
<zip object at 0x000000000358C188>
>>> for x in result:#遍历
...     
...     print(x) #结果变成元组
...     
('x', 1)
('y', 2)
('z', 3)

map用法:main.py 把一个数字乘以2

def double_number(x):
    return x * 2

l = [1,2,3,4,5]

result = list(map(double_number,l) ) #把l列表的每一个元素都应用函数double nmber,map是挨个传播

print(result)

 

 

函数:

1目的:最大化代码重用dry不用重复自己

           最小化代码冗余

           过程分解

2定义:def函数名(参数1,...):函数体

如计算两数相乘

 

def multiply(x, y): return x * y

 

3调用:函数名(实际参数)

def multiply(x, y):
    return x * y

print(multiply(3.14,5))

试试字符串能否相乘,发现可以:字符串的特性

print(multiply('优品课堂',5))

 

 

模拟看书过程:封装执行语句形成命令

def read_book():#重复利用()表面执行操作
    print('拿到一本书')#逻辑
    print('看书')
    print('收起')

read_book()#调用函数

 

#接收参数传递信息
def learning():
    print('报名')
    print('学习')
    print('退出')

learning()

细化信息:通过参数形式列举

#接收参数传递信息
def learning(name, course, start, end):#需要给相应的参数,形式参数
    print('{}报名课程:《{}》'.format(name,course))#格式化字符串
    print('从第{}节学习到第{}节.format(start, end)')
    print('{}学习结束.format(name)')

learning('Tom','Python入门',1,3)#实际应用,实际参数

可以从外面向里面传递信息,也可以从里面向外面传递信息

#learning('Tom','Python入门',1,3)#实际应用
def add_number(x,y): #计算两个数据和,add添加数字
    result = x + y #先声明一个result
    return result #返回一个值给调用者

#print(add_number(5,3))

a = 10
result = a + add_number(5,3)

print(result)

 假定两个序列找重复序列

def intersect(seq1, seq2): #两个序列以为是列表
    res = []#放入空列表
    for x in seq1: #找第一个序列元素放x里,声明参数是在本地定义一个变量
        if x in seq2: #如果第二个也有也放进去
            res.append(x) #放入空列表里

    return res

s1 = 'uke.cc'
s2 = 'youpinketang.com'

l = intersect(s1, s2)#放入一个新结果

print(l)#打印看有哪些

s1 = 'abcdefg'

实际开发方便用推导

4变量作用域

(1)Global全局:global

(2)local本地

x = 55

def func():#定义函数,函数里定义的作用的范围是它里面的属于本地的(local)
    x = 99 #赋值99
    print(x)

print('全局x:',x)
print('函数内x:')#函数内x为多少
func()# func是执行逻辑

全局55 内99

 如果想用全局的加个global

x = 55

def func():#定义函数
    global x
    x = 99 #x为外部的
    print(x)

print('全局x:',x)
print('函数内x:')#函数内x为多少
func()# func是执行逻辑
print('全局x:',x)

第一次:函数没执行是55,第二次x是外部的了,把x给改了打印的是99,第三次x已经改变所以为99

 (3)built-in:作用最范围广

(4)enclousure封装 :nonlocal

函数套函数:逻辑是先定义再调用

def func():#定义函数
    x = 100#第二次打印的是外侧x,外层x称之为封装
    def nested():#嵌套
        x = 99
        print(x)
    nested()#调用,第一次执行的是它
    print(x)

func()#func执行,自带print

 有时候也想用外侧的,可写声明nonlocal 非本地的

def func():#定义函数
    x = 100#第二次打印的是外侧x,外层x称之为封装
    def nested():#嵌套
        nonlocal x #非本地的
        x = 99
        print(x)
    nested()#调用,第一次执行的是它
    print(x)

func()#func执行,自带print

 

5参数

改变数字

def change_numer(x):#默认情况下参数定义没有写类型
    x += 10


x = 5 #传x为5整型不可改变

print('x={}'.format(x))#第一次打印x
change_numer(x) #执行改变操作
print('x={}'.format(x))#第二次再打x

改变列表

def change_list(l):
    l[0] = 99#传递过来的列表第一个元素标记为99

l = ['uke.cc','codeclassroom.com','youpinketang.com']
print('原始列表:',l)
change_list(l)
print('操作后列表:',l)

改变字符串

def change_str(s):
    s = 'uke.cc'


url = 'youpinketang.com'

print(url)
change_str(url)
print(url)

规律:参数   传递   不可变类型,传递副本给函数,函数内操作不影响原始值(int,float,str,tuple)

                                可变类型,传递地址引用,函数内操作可能会影响原始值(列表,字典表)

不变类型直接操作值,而列表只是个引用,改变了会影响它的值。

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!