python 基础汇总:
1.Python大小写敏感
2.Python是动态语言,即在定义变量时不需要指定变量类型
3.Python的整数合浮点数没有大小限制
4.python3 ,字符串是以Unicode 编码,Python的字符串支持多语言
5.当str和bytes互相转换的时候,需要指定编码,最常用的编码是UTF-8
list和tuple
list:列表,python内置的一种数据类型。是有序集合,可以添加或删除元素
classmates = ['Michal','Bob','Tracy']
常用方法:
1.获取元素的个数:len(classmates)
2.访问元素:classmates[0]
3.追加元素到末尾:classmates.append('s')
4.插入元素到指定位置:classmates.insert(1,'Jac')
5.删除末尾元素:classmates.pop()
6.删除指定位置元素,classmates.pop(i) i是索引位置
7.替换元素:classmates[1]='s'
8.list里面元素数据类型可以不同,L=['Apple',123,True]
9.List可以嵌套:s = ['python','java',['asp','php'],'scheme']
10.空List ,长度为0 L=[],len(L) 0
tuple:有序列表 一旦初始化就不能修改
不可变的意义:因为tuple不可变,代码更安全,尽可能用tuple代替list
1.定义空的tuple:t = ()
2.定义只有一个元素的tuple:t=(1,)
python循环:
-
for x in range(101):
sum = sum + x
2.while
dict:
d = {'Michae':95,'Bob':75,'Tracy':85}
1.判断key是否存在 'key' in d 返回True或False
2.dict的get()方法 d.get('key','不存在返回的值')
3.删除key :pop(key)
牢记dict的key必须是不可变对象
set:
和dict类似,是一组key的集合
1.创建set:需要提供一个list作为输入集合:s = set([1,2,3])
2.添加、删除元素 s.add() s.remove()
Python函数:
1.python内置常用函数:数据类型转换函数:
int()、float()、str()、bool()
2.函数定义格式:
def my_abs(x):
if x >= 0:
return x
else:
return -x
定义空函数:
def nop():
pass
函数同时返回多个值,其实就是一个tuple
3.python函数的参数非常灵活,可以使用默认参数可变参数和关键字参数
位置参数 :power(5,2)
默认参数:定义时,必选参数在前,默认参数在后
def power(x,n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
调用时可以按照顺序传入参数值,当不按顺序提供默然参数时,需要写上参数名。
在编写程序时,能使用不可变对象就使用不可变对象
可变参数:参数前面加一个*号,在函数内部,参数numbers接受到的是一个tuple
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
调用该函数时,可以传入任意个参数,包括0 个参数: calc(1,2) 或者calc()
如果已经有一个list或者tuple要调用一个可变参数,可以在list或者tuple 前面加一个* 号,把list或者tuple变成可变参数传进去:
nums = [1,2,3]
calc(*nums) # *nums 表示把nums这个list的所有元素作为可变参数传进去。这种写法很常用也很常见
关键字参数:
可变参数允许传入0个或任意个参数,这些可可变参数在调用时自动组装为一个tuple.
而关键字参数允许传入任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name,age,**kw):
print('name',name,'age',age,'other:',kw)
函数person 除了必选参数name和age外,还接受关键字参数kw,在调用时可以只传入必选参数:
>>> person('Michael', 30)
name: Michael age: 30 other: {}
也可以传入任意个数的关键字参数:
>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
关键参数的作用是可以扩展函数的功能,例如再做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足需求。
传入一个已经定义好的dict:
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
命名关键字参数
上面的关键字参数,函数的调用者可以传入任何不受限制的关键字参数。如果想限制关键子参数的名字,就可以用命名关键字参数,例如只接收city和job作为关键字参数。
def person(name,age,*,city,job): # * 后面的参数被视为命名关键字参数
print(name,age,city,job)
或者:
def person(name,age,*args,city,job): #已经有可变参数,不需要*
print(name,age,city,job)
命名关键字参数必须传入参数名,命名关键字参数可以有缺省值从而简化调用:
def person(name,age,*,city='Beijing',job):
print(name,age,city,job)
调用:
person('Jack',24,job='Engineer')
Jack 24 Beijing Engineer
参数组合
在python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。
但是,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。不要同时使用太多组合,否则函数接口的可理解性很差。
函数小结:
1.默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误。
2.注意可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dit.
3.调用函数时如何传入可变参数和关键字参数的语法:
可变参数可以直接传入:func(1,2,3) ,又可以先组装list或者tuple,再通过*args传入:func(*(1,2,3))
关键字参数既可以直接传入:func(a=1,b=2),右可以先组装dict,再通过**kw传入:func(**{'a':1,'b':2})
4.使用*args和**kw是Python的习惯写法
5.命名关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值
6.定义命名关键字参数在没有可变参数的情况下不要忘了写分隔符 * ,否则定义的将是位置参数。
递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自己本身,这个函数就是递归函数。
递归实现n的阶乘
def fac(n):
if n==1:
return 1
return n * fac(n - 1)
递归优点:定义简单,逻辑清晰,理论上所有递归函数都可以写循环的方式,但循环的逻辑不如递归清晰。
使用递归要防止栈溢出。在计算机中,函数调用时通过栈这种数据结构实现的,每当进入一个函数调用,栈就会增加一层栈,每当函数返回,栈就会减一层栈。由于栈的大小不是无限的,所以,递归调用过多会导致栈溢出。
解决递归调用栈溢出的办法是通过尾递归优化:在函数返回的时候调用自身本身,并且,return语句不能包含表达式。
def fac(n):
return fac_iter(n,1)
def fac_iter(num,product):
if num == 1:
return procduct
return fac_iter(num - 1,num * product)
可以看到,return fac_iter(num - 1,num * product) 仅返回递归函数本身
fac(5)的调用如下:
===> fact_iter(5, 1)
===> fact_iter(4, 5)
===> fact_iter(3, 20)
===> fact_iter(2, 60)
===> fact_iter(1, 120)
===> 120
Python高级特性
切片
1.取前3个元素
L[:3]
2.从索引1开始取两个元素
L[1:3]
3.取倒数两个元素(倒数第一个元素的索引是-1)
L[-2:-1]
4.前10个数,每两个取一个:
L[:10:2]
5.所有数,每5个取一个
L[::5]
tuple和字符串也可以切片,字符串切片实现字符串的截取操作
迭代
可迭代的对象都可以迭代
1.迭代字典的key(无序)
for key in d:
print(key)
2.迭代value: for value in d.values()
3.同时迭代key和value:for k,v in d.items()
4.判断是否可以迭代
from collection import Iterable
5.迭代下标和元素:enumerate函数可以把一个list变成 索引-元素对:
for i,value in enumerate(['A','B','C']):
print(i,value)
for循环同时引用两个变量是很常见的:
for x,yin [(1,1),(2,4),(3,9)]:
print(x,y)
1 1
2 4
3 9
列表生成式:创建list的生成式
1.写法
[x * x for x in range(1,11)]
2.加判断条件的列表生成式
[x * x for x in range(1,11) if x % 2 == 0] #仅筛选出偶数的平方
3.两层循环实现全排列
[m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
3.列表生成器列出当前目录下的所有文件和目录名
import os
[d for d in os.listdir('.')] #os.listdir可以列出文件和目录
4.列表生成器可以使用两个变量生成list:
d = {'x': 'A', 'y': 'B', 'z': 'C' }
[k + '=' +v for k,v in d.items()]
相当于
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> for k, v in d.items():
... print(k, '=', v)
5.把一个list中的所有字符串变成小写
L = ['Hello', 'World', 'IBM', 'Apple']
[s.lower() for s in L if isinstance(s,str)]
生成器
通过列表式,可以直接创建一个列表。
如果不一次性创建一个完整的list,而是在循环的过程中不断推算后续的元素,从而节省大量的空间。
在python中,这种一边循环一边计算的机制,称为生成器:genertor
创建genertor
1.列表生成式的[]改成()
L = [x * x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
g = (x * x for x in range(10))
g
<generator object <genexpr> at 0x1022ef630>
打印generator的元素:
一个一个打印:next()函数来获得generator的下一个返回值。generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到没有更多的元素时,抛出StopIteration的错误。通常不这么用。
正确的方法是使用for循环,因为generator 也是可迭代对象:
g = (x * x for x in range(10))
for n in g:
print(n)
2.函数内部包含yield关键字,这个函数就是一个generator:
def fib(max):
n,a,b = 0,0,1
while n < max:
yield b
a,b = b,a + b
n = n + 1
return 'done'
f = fib(6)
f
<generator object fib at 0x104feaaa0>
generator和函数的执行流程不一样,函数是顺序执行,遇到return语句或者最后一行函数语句就返回。
而generator函数,在每次执行next()的时候执行,遇到yiled语句返回,再次执行时从上次返回的yield语句处继续执行。
例子:
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
调用:
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
可以看到,odd不是普通函数,而是generator,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错。
拿到generator的返回值:捕获StopIteration异常,返回值包含在StopIteration的value中:
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
迭代器
可直接作用于for循环的数据类型有两类,这些可以直接作用于for循环的对象统称为可迭代对象:Iterable
一类是集合数据类型,如list、tuple、dict、set、str等
一类是generator
判断一个对象是否属于可迭代对象:isinstance()
from collections import Iterable
isinstance({},Iterable)
其中generator不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值。
可以被next()函数调用并不断返回下一个值的对象称为可迭代器:Iterator
使用isinstance()函数判断一个对象是否是Iterator对象:
for collections import Iterator
isinstance((x for x in range(10)),Iterator)
True
isinstance([],Iterator)
Flase
isinstance({},Iterator)
False
isinstance('abc',Iterator)
false
生成器都是Iterable对象,但list、dict、str虽然是Iterable,却不是Iterator,是因为Itertor对象表示的一个数据流,Itertor对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但是我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Itertor的计算是惰性的,只有在需要返回下一个数据时它才会计算。
list、dict、str、等Iterable变成Iterator可以使用iter()函数
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
Iterator可以表示一个无限大的数据流,例如全体自然数,而使用list是永远不可能存储全体自然数的。
小结:
1.凡是可作用于for循环的对象都是Iterable类型;
2.凡是可作用于next()函数的对象都是Iterator类型,它表示一个惰性计算的序列;
3.集合数据类型如list、dict、ste等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象
Python的for循环本质上就是通过不断调用next()函数实现的,例如:
for x in [1,2,3,4,5]
pass
完全等价于
#首先获得Iterator对象:
it = iter([1,2,3,4,5])
#循环:
while True:
try:
#获得下一个值:
x = next(it)
except StopIteration:
#遇到StopIteration就退出循环
break
函数式编程
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
高阶函数
一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数
map/reduce
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果