L=['a','b','c','d','e']
a=L[0:3] #取0,1,2
print(a) #['a', 'b', 'c']
a=L[:-1] #最后一个不取
print(a)#['a', 'b', 'c', 'd']
a=L[1:3]
print(a)#['b', 'c']
a=L[:] #什么也不写,全复制
print(a)#['a', 'b', 'c', 'd', 'e']
t=(1,2,3,4) #元组可以这么使用
print(t[0:3])
a='adhjfhjkd'[0:3]#字符串也可以切片
print(a)
def mytrim(s): #实现去除首位空字符串
if s==None or s=='':
return s
if s[0]==' ':
return mytrim(s[1:])
if s[-1]==' ':
return mytrim(s[:-1])
return s
print(mytrim(' he '))
#dict迭代
print(dict) #{'michael': 95, 'lang': 99, 'Eng': 200}
#迭代key
for key in dict:
print(key)
#迭代values
for value in dict.values():
print(value)
#同时迭代
for k,v in dict.items():
print(k,v)
'''
michael 95
lang 99
Eng 200
'''
for ch in 'ABC': #也可以迭代字符串
print(ch)
from collections.abc import Iterable
print(isinstance('abc',Iterable)) #判断字符串是否是可迭代对象(的实例) #true
#如果要实现下标循环,用enumerate把list变成索引元素对
for i,value in enumerate(['sss','dd','ee']):
print(i,value)
'''
0 sss
1 dd
2 ee
'''
def findMinAndMax(L):
min,max=L[0],L[0]
for num in L:
if num<min:
min=num
if num>max:
max=num
return (min,max)
print(findMinAndMax([7, 1, 3, 9, 5]))
print(findMinAndMax([3,5,6,1,5,0,34,6]))
# min=L[0],max=L[0] 不能这么赋值
1.分两行是可以的
# min=L[0]
# max=L[1]
2.两个变量同时赋值,逗号只能隔变量名
min,max=L[0],L[0]
L=[x*x for x in range(1,11)] #生成的元素x*x 放在for之前
print(L) #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
L=[x*x for x in range(1,11) if x%2==0] #for后面的if是过滤条件 此时后面不能有else
print(L) #[4, 16, 36, 64, 100]
#两层循环,全排列
L=[m+n for m in'ABC' for n in'XYZ']
print(L)
#if写在for前面,则必须有else
L=[x if x%2==0 else -x for x in range(1,11)]
print(L) #[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
L=(x*x for x in range(1,11)) #generator[]改为()
for n in L: #next(L)或者for循环,迭代
print(n)
def fib(max):
n,a,b=0,0,1
while n<max:
yield b #如果一个函数定义中包含yield关键字,那么这个函数就是generator函数,调用函数将返回一个generator
a,b=b,a+b
n+=1
return 'done'
f=fib(6) #generator函数在执行过程中,遇到yield就中断,下次从这个位置执行,直到没有yield可以执行
for i in fib(6):
print(i)
普通函数调用直接返回结果:
generator函数的调用实际返回一个generator对象:
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象:
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数:
from collections.abc import Iterator
print(isinstance([],Iterable)) #True
print(isinstance([],Iterator)) #False
print(isinstance(iter([]),Iterator)) #True
凡是可作用于
for循环的对象都是Iterable类型;凡是可作用于
next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;集合数据类型如
list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数!
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
一个最简单的高阶函数:
f=abs
def add(x,y,f):
return f(x)+f(y)
print(add(-5,-6,f)) #11
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
def f(x):
return x*x
r=map(f,[1,2,3,4,5,6,7])
print(list(r)) #[1, 4, 9, 16, 25, 36, 49]
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,
from functools import reduce #ATOI
def fn(x,y):
return x*10+y
def char2num(s):
digits={'0':0,'1':1,'2':2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
return digits[s]
print(reduce(fn,map(char2num,'1357'))) #1357
filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
def is_odd(n):
return n%2==1
print(list(filter(is_odd,[1,2,4,5,6,7,8]))) #[1, 5, 7]
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。对比原始的list和经过key=abs处理过的list:要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True:
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def count():
fs=[]
for i in range(1,4):
def f():
return i*i
fs.append(f)
return fs
f1,f2,f3=count()
print(f1(),f2(),f3()) #9 9 9
使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。
def inc():
x=0
def fn():
x+=1 #UnboundLocalError: local variable 'x' referenced before assignment
return x
return fn
f=inc()
print(f())
def inc():
x=0
def fn():
nonlocal x #要加声明
x+=1 #UnboundLocalError: local variable 'x' referenced before assignment
return x
return fn
f=inc()
print(f())#1
print(list (map(lambda x:x*x,[1,2,3,4,5,6,7])) ) #关键字lambda表示匿名函数,冒号前面的x表示函数参数,冒号后面是结果
#[1, 4, 9, 16, 25, 36, 49]
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
if __name__=='__main__':
test()
当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。
正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;
类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
之所以我们说,private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量。
private函数也一样