cjcmay 发表于 2018-8-7 08:45:20

Python Day4

迭代器:迭代的工具
  #1 什么是迭代:指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值
  #2 为什么要有迭代器?
  #对于序列类型:str,list,tuple,可以依赖索引来迭代取值,
  #但是对于dict,set,文件,python必须为我们提供一种不依赖于索引的迭代取值的方式-》迭代器
  #3 可迭代的对象(下列都是):obj.iter
  

name='egon'  
l=
  
t=(1,2,3)
  
d={'name':'egon','age':18,'sex':'male'}
  
s={'a','b','c'}
  
f=open('a.txt','w',encoding='utf-8')
  

  
name.__iter__
  
l.__iter__
  
t.__iter__
  
d.__iter__
  
s.__iter__
  
f.__iter__
  

  #4 迭代器对象(文件是):obj.iter,obj.next
  

f.__iter__  
f.__next__
  

  #总结:
  #1 可迭代对象不一定是迭代器对象
  #2 迭代器对象一定是可迭代的对象
  #3 调用obj.iter()方法,得到的是迭代器对象(对于迭代器对象,执行iter得到的仍然是它本身)
  #for循环就是依赖的将可迭代对象转换为迭代器对象,然后进行迭代
  #总结迭代器的优缺点:
  #优点:
  #1、提供一种统一的、不依赖于索引的取值方式,为for循环的实现提供了依据
  #2、迭代器同一时间在内存中只有一个值——》更节省内存,
  #缺点:
  #1、只能往后取,并且是一次性的
  #2、不能统计值的个数,即长度
  

l=  
l
  
l
  
l
  
l
  

  
l_iter=l.__iter__()
  
# print(l_iter)
  
print(next(l_iter))
  
print(next(l_iter))
  
print(next(l_iter))
  

生成器
  #1 什么是生成器:只要在函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器
  #生成器就是迭代器
  #yield的功能:
  #1、yield为我们提供了一种自定义迭代器对象的方法
  #2、yield与return的区别1:yield可以返回多次值 #2:函数暂停与再继续的状态是由yield帮我们保存的
  #模拟tail -f access.log |grep 404
  

import time  
def tail(file):
  with open(file,'rb') as f:
  f.seek(0,2)
  while True:
  line = f.readline()
  if line:
  yield line
  else:
  time.sleep(0.05)
  

  
lines=tail('access.log')
  

  
def grep(lines,pattern):
  for line in lines:
  line = line.decode('utf-8')
  if pattern in line:
  print(line)
  

  
grep(tail('access.log'),'404')
  

  #了解知识点:yield表达式形式的用法
  

def eater(name):  print('%s 开始吃饭' %name)
  food_list=[]
  while True:
  food=yield food_list #food=yield='鸡丁'
  food_list.append(food)
  print('%s start to eat %s' %(name,food))
  

  
e=eater('dzm')
  
#需要先初始化
  
next(e)
  
#然后e.send:1 从暂停的位置将值传给yield2、与next一样
  
print(e.send('米饭'))
  
print(e.send('鸡丁'))
  

三元表达式
  

def my_max(x,y):  if x > y:
  return x
  else:
  return y
  

  
res=my_max(10,20)
  
print(res)
  

  #示例一
  

x=10  
y=20
  
res=x if x > y else y
  

  
print(res)
  

  #示例二
  

name=input('>>: ').strip()  

  
res='sb' if name == 'alex' else 'nb'
  
print(res)
  

列表推导式
  #示例一
  

l=[]  
for i in range(1,11):
  res='egg'+str(i)
  l.append(res)
  

  
print(l)
  

  
l=['egg'+str(i) for i in range(1,11)]
  
print(l)
  

  #示例二
  

l1=['egg'+str(i) for i in range(1,11) if i >= 6]  
print(l1)
  

  
l1=[]
  
for i in range(1,11):
  if i >= 6:
  l1.append('egg'+str(i))
  

生成器表达式
  #把列表推导式的[]换成()就是生成器表达式
  #生成器比较节省内存
  

g=('egg'+str(i) for i in range(0,1000000000000000000000000000000000))  
print(g) #显示结果g是个生成器
  
print(next(g))
  
print(next(g))
  
print(next(g))
  

  #示例
  with open('a.txt','r',encoding='utf-8') as f:
  #求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)
  print(max(len(line)for line in f))
  #求文件a.txt中总共包含的字符个数
  print(sum(len(line) for line in f))

递归
  #递归调用:在调用一个函数的过程中,直接或者间接又调用该函数本身,称之为递归调用
  #递归必备的两个阶段:1、递推2、回溯
  #python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,但是python又没有尾递归,且对递归层级做了限制
  #举例,计算age(5)的数值
  

# age(5) = age(4) + 2  
# age(4) = age(3) + 2
  
# age(3) = age(2) + 2
  
# age(2) = age(1) + 2
  
#
  
# age(1) = 18
  

  
def func(n):
  if n == 1:
  return 18
  else:
  return func(n-1)+2
  

  
res=func(5)
  
print(res)
  

  #总结递归的使用:
  #1. 必须有一个明确的结束条件
  #2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
  #3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

二分法
  #了解的知识点
  l= #从小到大排列的数字列表,找到301
  

def search(l,num):  print(l)
  if len(l) == 0:
  print('没有这个内容')
  return
  mid_index = len(l) // 2
  if num > l:
  search(l,num)
  elif num < l:
  search(l,num)
  else:
  print(num)
  

  
x=int(input('请输入数字: '))
  
search(l,x)
  

匿名函数
  

def func(): #func=内存地址  print('from func')
  

  
func()
  

  #上面这是有名函数
  #举例
  #内存地址
  

def my_sum(x,y):  return x+y
  

  #把上面有名函数变为匿名函数
  #自带return返回值效果
  print(lambda x,y:x+y)
  #打印后得到一个内存地址
  #给这个内存地址传参执行
  print((lambda x,y:x+y)(1,2))
  #得到3
  #也可以:
  

func=lambda x,y:x+y  
#print(func)
  
print(func(1,2))
  

  #lambda匿名函数通常跟别的函数配合使用
  #匿名意味着引用计数为0,使用一次就释放,除非让其有名字

内置函数(与匿名函数配合使用)
  #max,min,sorted,map,reduce,filter
  #上面的函数都遵循迭代器对象
  #next一次取一次值
  #字典的运算:最小值,最大值,排序
  

salaries={  'egon':3000,
  'alex':100000000,
  'wupeiqi':10000,
  'yuanhao':2000
  
}
  

  #zip 拉链
  

s='hello'  
l=
  
g=zip(s,l)
  

  #g是一个内存地址
  #zip的结果是一个迭代器
  

print(list(g))  
#结果
  
[('h', 1), ('e', 2), ('l', 3)]
  

  #使用列表形式表现出来,从结果可以看出一一对应的保存在一个小元祖中
  #max函数
  #举例,求上面字典中工资最高的人名
  #方法1,可以和上面的zip函数配合
  g=zip(salaries.values(),salaries.keys())
  #这样就可以按照薪资value比较,字典默认按照keys比较
  print(max(g))
  #结果
  (100000000, 'alex')
  #方法2,与匿名函数配合
  print(max(salaries,key=lambda x:salaries))
  #结果:
  alex
  #'key='表示指定max函数比较的依据
  #'k'是前面每次循环salaries后得到的字典的key,salaries的结果返回给前面的key
  #也就是说这里使用字典中的value进行比较,但显示的还是比较后结果所对应的字典中的key
  #min函数
  #用法跟max相同
  print(min(salaries,key=lambda k:salaries))
  #sorted 排序
  #与max用法相同
  print(sorted(salaries,key=lambda k:salaries))
  #还可以加个reverse=True将结果反转
  print(sorted(salaries,key=lambda k:salaries,reverse=True))
  #map,reduce,filter
  #map 映射
  #举例说明:
  #将列表中的字符串后面都加上_SB
  

names=['alex','wupeiqi','yuanhao']  
l=[]
  
for name in names:
  res='s%_SB' %name
  l.append(res)
  
print(l)
  

  #使用map函数实现
  

g=map(lambda name:'%s_SB' %name,names)  
print(list(g))
  

  #结果:
  ['alex_SB', 'wupeiqi_SB', 'yuanhao_SB']
  #filter 过滤
  

names=['alex_SB', 'wupeiqi_SB', 'yuanhao_SB','egon']  
g=filter(lambda x:x.endswith('SB'),names)
  
print(list(g))
  

  #结果:
  ['alex_SB', 'wupeiqi_SB', 'yuanhao_SB']
  #reduce 合并
  

from functools import reduce  
print(reduce(lambda x,y:x+y,range(1,101)))
  

  #结果
  

5050  
print(reduce(lambda x,y:x+y,range(1,101),100))
  

  #结果
  5150
  #最后的100是初始值,原本初始值是1,现在改为100

内置函数
  #需要掌握
  #divmod 得到商和余
  

print(divmod(10001,25))  
(400, 1)
  

  #只要余不为0就需要加1
  #enumerate
  #对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值
  #enumerate多用于在for循环中得到计数
  

l=['a','b','c']  
for i,v in enumerate(l):
  print(i,v)
  

  #结果:
  

0 a  
1 b
  
2 c
  

  #enumerate还可以接收第二个参数,用于指定索引起始值,如:
  

list1 = ["这", "是", "一个", "测试"]  
for index, item in enumerate(list1, 1):
  print(index, item)
  

  #结果:
  1 这
  2 是
  3 一个
  4 测试
  #补充
  #如果要统计文件的行数,可以这样写:
  #利用enumerate():
  

count = 0  
for index, line in enumerate(open(filepath,'r')):
  count += 1
  

  #eval
  #将字符串str当成有效的表达式来求值并返回计算结果
  #将字符串转成相应的对象,转换成列表,转换成字典,转换成元组等
  

res=eval('')  
print(res,type(res))
  

  #结果:
   &lt;class 'list'&gt;
  #pow
  

res=pow(2,3,3) #2的三次方的结果对3取余  
print(res)
  

  #结果:
  2
  #round 四舍五入
  

print(round(3.5))  
4
  

  #slice 切片
  #制造一个切片格式
  

l=['a','b','c','d','e','f']  
s=slice(1,5,2)
  
print(l)
  

  #结果:
  ['b', 'd']
页: [1]
查看完整版本: Python Day4