1.python简介
缺点:1.运行速度慢
2.不能加密
2.输入和输出
输出:print()函数也可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出:
例如: print(“hello world”,”你好”,”yamaha”)
输出结果:hello world 你好 yamaha
注意:print()会依次打印每个字符串,遇到逗号“,”会输出一个空格,因此,输出的字符串是这样拼起来的。
输入:Python提供了一个input(),可以让用户输入字符串,并存放到一个变量里。比如输入用户的名字:
name=input()
输入:mile
输出:mile
但是程序运行的时候,没有任何提示信息告诉用户:“嘿,赶紧输入你的名字”,这样显得很不友好。幸好,input()可以让你显示一个字符串来提示用户,于是我们把代码改成:
name=input(“please enter your name:”);
print(“hello”,name)
3.python基础
1.以#开头的语句是注释,大小写敏感,4个空格作为缩进。
2.数据类型:整型,浮点型
字符串:单引号,双引号,三引号
布尔值:只有True、False两种取值,布尔值可以用and、or和not运算。主要用于条件表达式中
例如:if age >= 18:
print(‘adult’)
else:
print(‘teenager’)
空值:空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是
一个特殊的空值。
3.变量
变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和_的组合,且不能用数字开头。
注意理解变量在计算机内存中的表示也非常重要!!!!
a = ‘ABC’时,Python解释器干了两件事情:
在内存中创建了一个’ABC’的字符串;
在内存中创建了一个名为a的变量,并把它指向’ABC’。
最后解释一下整数的除法为什么也是精确的。在Python中,有两种除法,一种除法是/
10/3 //3.33333333333333333精确除
10//3 //3 类似java中的/
4.字符串和编码
对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:
len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:可见,1个中文字符经过UTF-8编码后会占
用3个字节,而1个英文字符只占用1个字节。
5.list和tuple
list是一种有序的可变的集合,集合中数据类型可以不同,可以随时添加和删除其中的元素。
list=[‘bob’,13,[‘alice’,True]]
len(list) //返回list中元素的个数
list[i] //访问list中第i个位置的元素
list[-i] //取倒数第i个元素
list.append(xxx) //向末尾添加元素
list.insert(2,”jack”) //向第二个位置添加指定元素
list.pop() //删除末尾元素,返回值是删除的元素
list.pop(i) //删除指定位置i上的元素,返回值是删除的元素
list[2][0] //返回结果是’alice’
list[0]=’tom’ //更新指定位置的值
另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改,
不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧 义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。
所以,只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:
t=(1,)
6.dict和set
请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。要创建一个set,需要提供一个list作为输入集合.
s=set([1,2,3,3,4]) //创建set{1,2,3,4}
s.add(5) //添加元素5
s.remove(5)//移除元素5
set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错。
7.python函数
1)内置函数:abs(),max(),min()等等,Python内置的常用函数还包括数据类型转换函数,比如int()函数可以把其他数据类型转换为整数。
注意:函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”。
a=abs;
a(-1) //输出1
2)定义函数
def my_abs(x):
if x >= 0:
return x
else:
return -x
注意:如果想定义一个什么事也不做的空函数,可以用pass语句,实际上pass可以用来作为占位符。
注意:函数可以返回多个值吗?答案是肯定的。原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
小结:定义函数时,需要确定函数名和参数个数;
如果有必要,可以先对参数的数据类型做检查;
函数体内部可以用return随时返回函数结果;
函数执行完毕也没有return语句时,自动return None。
函数可以同时返回多个值,但其实就是一个tuple。
8.函数的参数
1)默认参数:设置默认参数时,有几点要注意:
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数。所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
2)定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数.
3)关键字参数:
而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):
print(‘name:’, name, ‘age:’, age, ‘other:’, kw)
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,然后,把该dict转换为关键字参数传进去:
extra = {‘city’: ‘Beijing’, ‘job’: ‘Engineer’}
person(‘Jack’, 24, **extra)
name: Jack age: 24 other: {‘city’: ‘Beijing’, ‘job’: ‘Engineer’}
注意:**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
4)命名关键字参数:
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
def person(name, age, *, city, job):
print(name, age, city, job)
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名:
person(“tom”,12,city=”wuhan”,job=”stu”) //正确
person(“tom”,12,”wuhan”,”stu”) //错误
命名关键字参数可以有缺省值,从而简化调用:
def person(name, age, *, city=’Beijing’, job):
print(name, age, city, job)
由于命名关键字参数city具有默认值,调用时,可不传入city参数:
person(‘Jack’, 24, job=’Engineer’)
Jack 24 Beijing Engineer
使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个作为特殊分隔符。如果缺少,Python解释器将无法识别位置参数和命名关键字参数:
def person(name, age, city, job):
# 缺少 *,city和job被视为位置参数
pass
5)参数组合:
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
def f1(a, b, c=0, *args, **kw):
print(‘a =’, a, ‘b =’, b, ‘c =’, c, ‘args =’, args, ‘kw =’, kw)
小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过kw传入:func({‘a’: 1, ‘b’: 2})。
使用*args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。
Python高级特性
1.切片
L = [‘Michael’, ‘Sarah’, ‘Tracy’, ‘Bob’, ‘Jack’],取前3个元素,应该怎么做?
L[0:3] //从索引0开始取,直到索引3为止,但不包括索引3,0可以省略。
既然Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片
L[-2:] //取倒数两个元素
L[:3:2]//取前三个,每两个取取一个
注意:切片操作对list.tuple.str均有效。
2.迭代
因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代:
dict={“a”:”tom”,”b”:”jerry”,”c”:”bob”}
for key in dict:
print(key)
注意:因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。
如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i,value in enumerate([“tom”,”jey”,”maek”]):
print(i,value)
输出结果是:0 tom
1 jey
2 maek
小结:任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环。
3.列表生成式
1)写列表生成式时,把要生成的元素放到前面,后面跟for循环,就可以把list创建出来
例如:生成1道10平方值的列表
[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
2)or循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方
[x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
3)还可以使用两层循环,可以生成全排列
[m + n for m in ‘ABC’ for n in ‘XYZ’]
[‘AX’, ‘AY’, ‘AZ’, ‘BX’, ‘BY’, ‘BZ’, ‘CX’, ‘CY’, ‘CZ’]
4.生成器
1)通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
2)要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator
L = [x * x for x in range(10)]
L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
g = (x * x for x in range(10))
g
Python的for循环本质上就是通过不断调用next()函数实现的。
函数式编程
1.高阶函数
1)函数本身也可以赋值给变量,即:变量可以指向函数
f = abs
f(-10)
10
成功!说明变量f现在已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同。
2)函数名也是变量
函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数!
abs = 10
abs(-10)
Traceback (most recent call last):
File “”, line 1, in
TypeError: ‘int’ object is not callable
3)传入参数
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def add(x,y,f):
return f(x)+f(y)
r=add(-5,6,abs)
print(r)
输出:11
2.map/reduce
1)map
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
def f(x):
… return x * x
…
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
2)reduce
reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
3.filter()
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
例如,在一个list中,删掉偶数,只保留奇数,可以这么写:
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
结果: [1, 5, 9, 15]
注意:filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。
4.sorted
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序.用sorted()排序的关键在于实现一个映射函数。
5.返回函数
一个函数可以返回一个计算结果,也可以返回一个函数。
返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。
6.匿名函数
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
f = lambda x: x * x
f
7.装饰器
这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
8.偏函数
简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
python模块
1.