公司建议使用Python,而后本身经过百度和向有学过Python的同窗了解了Python。Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数据分析这方面。在将来我以为是往自动化,人工智能这方面发展的,因此学习了Python。
自学,练项目,到GitHub上面找一些小项目学习。
Python属于解释型语言,当程序运行时,是一行一行的解释,并运行,因此调式代码很方便,开发效率高,还有龟叔给Python定位是任其自由发展、优雅、明确、简单,因此在每一个领域都有建树,全部它有着很是强大的第三方库,
特色:
语法简洁优美,功能强大,标准库与第三方库都很是强大,并且应用领域也很是广;
可移植性,可扩展性,可嵌入性。
缺点:
运行速度慢。
- 解释型 - Python/php (java、C 编译型) - 弱类型
- Python (java、C 强类型)
- 动态语言
- Python (java、C 静态型)
(1)与Java相比:在不少方面,Python比java要简单,好比java中全部变量必须声明才能使用,而Python不须要声明,用少许的代码构建出不少功能;(高效的高级数据结构)php
(2)与PHP相比:python标准包直接提供了工具,而且相对于PHP代码更易于维护;java
(3)Python与C相比:python
Python 和 C Python这门语言是由C开发而来mysql
对于使用:Python的类库齐全而且使用简洁,若是要实现一样的功能,Python 10行代码能够解决,C可能就须要100行甚至更多.
对于速度:Python的运行速度相较与C,绝逼是慢了git
一、Python 易于学习;redis
二、用少许的代码构建出不少功能;(高效的高级数据结构)算法
三、Python 拥有最成熟的程序包资源库之一;sql
四、Python彻底支持面向对象;shell
五、Python 是跨平台且开源的;数据库
六、动态类型.
解释型:就是边解释边执行(Python,php) 编译型:编译后再执行(c、java、c#)
1字节 = 8 位
位(bit),数据存储是以“字节”(Byte)为单位,数据传输是以大可能是以“位”(bit,又名“比特”)为单位,
一个位就表明一个0或1(即一个二进制),二进制是构成存储器的最小单位,每8个位(bit,简写为b)组成一个字节(Byte,简写为B),
字节是最小一级的信息单位。
b --->位(bit)
B --->字节 一个字节等于8位
1B = 8 bit
1kb = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
一、使用4个空格而不是tab键进行缩进。 二、每行长度不能超过80 三、使用空行来间隔函数和类,以及函数内部的大块代码 四、必要时候,在每一行下写注释 五、使用文档注释,写出函数注释 六、在操做符和逗号以后使用空格,可是不要在括号内部使用 七、命名类和函数的时候使用一致的方式,好比使用CamelCase来命名类,使用lower_case_with_underscores来命名函数和方法 八、在类中老是使用self来做为默认 九、尽可能不要使用魔法方法 十、默认使用UTF-8,甚至ASCII做为编码方式
十一、换行可使用反斜杠,最好使用圆括号
十二、不要在一句import中多个库
空格的使用:
包名小写(不含下划线),函数名小写(可含下划线),常量名大写(可含下划线),类名驼峰写法,类属性小写(可含下划线)。
# 二进制转换成十进制-->int v = "0b1111011" b = int(v,2) print(b) # 123 # 十进制转换成二进制--->bin v2 = 18 print(bin(int(v2))) # 0b10010 # 八进制转换成十进制 v3 = "011" print(int(v3,8)) # 11 # 十进制转换成八进制:---> oct v4 = 30 print(oct(int(v4))) # 0o36 # 十六进制转换成十进制: v5 = "0x12" print(int(v5,16)) # 18 # 十进制转换成十六进制:---> hex v6 = 87 print(hex(int(v6))) # 0x57
请编写一个函数实现将IP地址转换成一个整数。 如 10.3.9.12 转换规则为: 10 00001010 3 00000011 9 00001001 12 00001100 再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ? def v1(addr): # 取每一个数 id = [int(x) for x in addr.split(".")] print(id) return sum(id[i] << [24, 16, 8, 0][i] for i in range(4)) print(v1("127.0.0.1")) # [127, 0, 0, 1] # 2130706433
1. 求结果:1 or 3 print(1 or 3) # 1 2. 求结果:1 and 3 print(1 and 3) # 3 3. 求结果:0 and 2 and 1 print(0 and 2 and 1) # 0 4. 求结果:0 and 2 or 1 print(0 and 2 or 1) # 1 5. 求结果:0 and 2 or 1 or 4 print(0 and 2 or 1 or 4) # 1 6. 求结果:0 or Flase and 1 print(0 or False and 1) # Flase 总结: # x or y 若是 x为真,则值为x, 不然为y # x and y 若是 x 为真,则值为 y,不然为 x
1. 求结果:2 & 5(与)
print(2 & 5) # 10 & 101 => 000 => 0
2. 求结果:2 ^ 5即2 | 5(或)
print(2 ^ 5) # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7
Python2内容进行编码(默认ascii),而Python3对内容进行编码的默认为unicode。 ascii 最多只能用8位来表示(1个字节),即:2**8 = 256,因此,ASCII码最多只能表示 256 个符号。 unicode 万国码,任何一个字符占2个字节 utf-8 万国码的升级版 一个中文字符占3个字节 英文是1个字节 欧洲的是2个字节 gbk 国内版本 一个中文字符占2个字节 英文是1个字节 gbk 转 utf-8 需经过媒介 unicode
机器码,学名机器语言指令,有时也被称为原生码,是电脑的CPU可直接解读的数据。
字节码是一种中间状态(中间码)的二进制代码(文件)。须要直译器转译后才能成为机器码。
什么是机器码 机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。 一般意义上来理解的话,机器码就是计算机能够直接执行,而且执行速度最快的代码。
总结:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,可是很是晦涩难懂,也比较难编写 什么是字节码 字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。
字节码是一种中间码,它比机器码更抽象,须要直译器转译后才能成为机器码的中间代码。 总结:字节码是一种中间状态(中间码)的二进制代码(文件)。须要直译器转译后才能成为机器码。
#is 比较的是内存地址 #== 比较的是值 #int 具备范围:-5---256 #对于int小数据池 范围:-5----256 建立的相间的数字,都指向同一个内存地址 #对于字符串 一、小数据池 若是有空格,那指向两个内存地址, 二、长度不能超过 20 三、不能用特殊字符 i = 'a'*20 j = 'a'*20 print(i is j) # True i = "a"*21 j = "a"*21 print(i is j) # False
应用场景:简化if语句
# 关于三元运算 # 结果+ if + 条件 + else + 结果 result='gt' if 1>3 else 'lt' print(result) # lt # 理解:若是条件为真,把if前面的值赋值给变量,不然把else后面的值赋值给变量。 lambda 表达式 temp = lambda x,y:x+y print(temp(4,10)) # 14 可替代: def foo(x,y): return x+y print(foo(4,10)) # 14
1:打印时,py2须要能够不须要加括号,py3 须要 python2 :print ('lili') , print 'lili' python3 : print ('lili') python3 必须加括号 exec语句被python3废弃,统一使用exec函数。 2:内涵 Python2:1,臃肿,源码的重复量不少。 2,语法不清晰,掺杂着C,php,Java,的一些陋习。 Python3:几乎是重构后的源码,规范,清晰,优雅。 三、输出中文的区别 python2:要输出中文 需加 # -*- encoding:utf-8 -*- Python3:直接搞 4:input不一样 python2 :raw_input python3 :input 统一使用input函数 5:指定字节 python2在编译安装时,能够经过参数-----enable-unicode=ucs2 或-----enable-unicode=ucs4分别用于指定使用2个字节、4个字节表示一个unicode; python3没法进行选择,默认使用 ucs4 查看当前python中表示unicode字符串时占用的空间: impor sys print(sys.maxunicode) #若是值是65535,则表示使用usc2标准,即:2个字节表示 #若是值是1114111,则表示使用usc4标准,即:4个字节表示 6: py2:xrange(返回列表) range(返回生成器) py3:range 统一使用range,Python3中range的机制也进行修改并提升了大数据集生成效率。 7:在包的知识点里 包:一群模块文件的集合 + __init__ 区别:py2:必须有__init__ py3:不是必须的了 8:不相等操做符"<>"被Python3废弃,统一使用"!=" 9:long整数类型被Python3废弃,统一使用int 10:迭代器iterator的next()函数被Python3废弃,统一使用next(iterator) 11:异常StandardError 被Python3废弃,统一使用Exception 12:字典变量的has_key函数被Python废弃,统一使用in关键词 13:file函数被Python3废弃,统一使用open来处理文件,能够经过io.IOBase检查文件类型
a = 1
b = 2
a, b = b, a
在python3里,只有一种整数类型int。大多数状况下,和python2中的长整型相似。
都在循环时使用,xrange内存性能更好,xrange用法与range彻底相同,range一个生成list对象,xrange是生成器。
要生成很大的数字序列的时候,用xrange会比range性能优不少,由于不须要一上来就开辟一块很大的内存空间。
在Python2中:
range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列
xrange用法与range彻底相同,所不一样的是生成的不是一个数组,而是一个生成器。
由上面的示例能够知道:要生成很大的数字序列的时候,用xrange会比range性能优不少,由于不须要一上来就开辟一块很大的内存空间,这两个基本上都是在循环的时候用。
在 Python3 中,range() 是像 xrange() 那样实现,xrange()被抛弃。
readlines 返回一个列表
xreadlines 返回一个生成器
0,"",{},[],(),set(),False,负数,不成立的表达式,None,等。
字符串:
字符串用单引号(')或双引号(")括起来,不可变。
s.strip(c):去除空格或指定的字符c;lstrip/rstrip;
s.zfill(w):右对齐,宽度小于w用0前补;
s.ljust(w,c):左对齐,宽度w,填充符c;rjust()右对齐。
s.join(q):用"s"将序列"q"中的元素串起来;
s.partition(sep):以sep为分隔符,把字符串分割,返回一个元组(包含分割符);
s.split(sep=None, maxsplit=-1):把字符串以sep为分隔符分割,maxsplit为分割次数,返回一个列表(不包含分割符);
s.find(t):返回t的最左位置,未找到,返回-1;
s.index(t):返回t的最左位置,未找到,返回ValueError异常;
s.capitalize():第一个字母变大写;
s.title():每一个单词首字母大写;
s.center(width, fillchar=None):字符串内容居中,在给定的字符串长度width中内容居中,两边用提供的字符fillchar填充,fillchar默认为空;
s.count(sub, start=None, end=None):在指定位置start与end之间,计算sub字符的数量;
s.endswith(suffix, start=None, end=None):判断字符串在start与end位置之间是否是以某个子序列suffix结尾,相似方法还可有startwith();
s.replace(old, new, count=None):把字符串中某个子序列old替换成一个新序列new,count是替换数,返回一个新字符串;
s.isdigit():判断是否全是数字;
s.isalpha():判断是否全是字母;
s.isalnum():判断是否包含字母或数字;
s.isspace():判断是不是空字符串;
s[start:stop:step]:切片,截取子字符串。
字典:
1:无序(不能索引) 2:数据关联性强 3:键值对,键值对。惟一一个映射数据类型。 字典的键必须是可哈希的,不可变类型。 在同一个字典中,键(key)必须是惟一的。
列表是有序的对象集合,字典是无序的对象集合。二者之间的区别在于:字典当中的元素是经过键来存取的,而不是经过偏移存取
1)clear(self):清除字典中的全部元素。
2)copy(self):复制一份元组,至关于一次浅拷贝。
3)fromkeys(self, iter, value=None):分别以iter中的元素为键,以value为值,建立一个字典。
4)get(self, k, d=None):获取字典中键为k的值,若是字典中不包含k,则给出d值,d默认为None。
5)items(self):遍历字典的一个方法,把字典中每对key和value组成一个元组,并把这些元组放在一个相似列表的dict_items中返回。
6)keys(self):遍历字典键keys的一个方法,返回一个相似列表的dict_keys,与items方法用法相同。
7) values(self):遍历字典值value的一个方法,返回一个相似列表的dict_values,与items方法用法相同。
8)pop(self, k, d=None):弹除并返回字典中键为k的值。
9)popitem(self):从字典中随机取出一组键值,返回一个新的元组。
10)setdefault(self, k, default=None):从字典中获取键为k的值,当存在k时,功能和get基本一致,当字典中不存在k时,在原字典上添加键为k、值为default的项,并返回default值。
11)update(self, E=None, **F):给字典新增元素,没有返回值。用法:dict.update(dict2)。
列表:
索引,切片,加,乘,检查成员。 一、List写在方括号之间,元素用逗号隔开。 二、和字符串同样,list能够被索引和切片。 三、List可使用+操做符进行拼接。 四、List中的元素是能够改变的。
1)append(self, p_object):在原有列表最后位置上追加新元素到列表,不生成新的列表。
2)clear(self):清空列表里面的元素,不生成新列表。
3)copy(self):复制一份列表,至关于一次浅拷贝。
5)extend(self, iterable):把iterable中的每一个元素扩展成列表的元素,iterable能够是字符串、列表、集合、元组、字典。
6)index(self, value, start=None, stop=None):查找列表中value元素索引位置,start与stop参数是查找起始与结束位置,默认为None。
7)insert(self, index, p_object):在列表index索引位置插入元素p_object,当index大于列表包含的元素个数时,在最后位置插入元素。
8)pop(self, index=None):从列表中取出index位置的值,index默认为None,此时弹除并返回列表中最后一个值。
9)remove(self, value):移除列表中第一个出现的value元素,value元素不存在列表中时,则抛出ValueError。
10)reverse(self):反转列表元素的位置。
11)sort(self, key=None, reverse=False):给列表中的元素排序,改变原列表!reverse默认False(升序)。【而sorted()函数是生成副本】。
12)[start:stop:step]:切片,从列表中取出一部分元素生成一个新列表,start与stop默认为None,step表示步长值,默认是一个接着一个切取,
若是为2,则表示进行隔一取一操做。步长值为正时表示从左向右取,若是为负,则表示从右向左取。步长值不能为0。
13)索引[index]:获取索引位置index的值。
元组:
()元组的元素不能修改。 一、与字符串同样,元组的元素不能修改。 二、元组也能够被索引和切片,方法同样。 三、注意构造包含0或1个元素的元组的特殊语法规则。 四、元组也可使用+操做符进行拼接。
1)count(self, value):统计元组中包含value元素的数量,返回一个int值。
2)index(self, value, start=None, stop=None):索引,查找元组中value元素第一个出现的位置,start与stop参数是查找起始与结束位置,默认为None。
3)[start:stop:step]:切片操做。
Set(集合):
集合(set)是一个无序不重复元素的序列。 可使用大括号 { } 或者 set() 函数建立集合,注意:建立一个空集合必须用 set() 而不是 { },由于 { } 是用来建立一个空字典。
1)add(self, *args, **kwargs):在集合里添加一个元素,不生成新的集合。
2)clear(self, *args, **kwargs):清空集合里面的元素,不生成新的集合。
3)copy(self, *args, **kwargs):浅拷贝集合,返回一个新集合。
4)difference(self, *args, **kwargs):传入一个或多个参数集合对比,返回一个与参数集合不同元素的集合。
5)discard(self, *args, **kwargs):删除集合中的某个元素,若是这个元素没有在集合中,不作操做。
6)isdisjoint(self, *args, **kwargs):对比两个集合,若空交集则返回True,没有则返回False。
7)issubset(self, *args, **kwargs):判断集合的包含关系,是不是参数集合的子集。
8)pop(self, *args, **kwargs):从集合中随机(因集合无序)弹除并返回一个元素,若是集合为空,则报TypeError错误。
9)remove(self, *args, **kwargs):移除集合中的一个元素,这个元素必须在集合中,若是不在,则报TypeError错误。
10)union(self, *args, **kwargs):两个集合拼接返回一个新集合。
11)update(self, *args, **kwargs):更新集合,添加集合中没有的新元素,不返回新集合。
匿名函数:为了解决那些功能很简单的需求而设计的一句话函数。 函数名 = lambda 参数 :返回值 #参数能够有多个,用逗号隔开 #匿名函数无论逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值 #返回值和正常的函数同样能够是任意数据类型 lambda 表达式 temp = lambda x,y:x+y print(temp(4,10)) # 14 可替代: def foo(x,y): return x+y print(foo(4,10)) # 14
pass是空语句,是为了保持程序结构的完整性。pass 不作任何事情,通常用作占位语句。
*arg 表明位置参数,它会接收任意多个参数并把这些参数做为元祖传递给函数。
**kwargs 表明的关键字参数,返回的是字典,位置参数必定要放在关键字前面。
a = 'lishi' str1 = "li" str2 = "shi" str3 = str1 + str2 print("a == str3",a == str3) print("a is str3",a is str3) print("id(a)",id(a)) print("id(str3)",id(str3)) # a == str3 ,True == ---> 只须要内容相等 # a is str3 ,False is ---> 只须要内存地址相等 # id(a) 38565848 # id(str3) 39110280
is 比较的是两个实例对象是否是彻底相同,它们是否是同一个对象,占用的内存地址是否相同。 == 比较的是两个对象的内容是否相等,即内存地址能够不同,内容同样就能够了。默认会调用对象的 __eq__()方法。
浅拷贝只是增长了一个指针指向一个存在的地址,而深拷贝是增长一个指针而且开辟了新的内存,这个增长的指针指向这个新的内存。采用浅拷贝的状况,释放内存,会释放同一内存,深拷贝就不会出现释放同一内存的错误。
一层的状况:
import copy # 浅拷贝 li1 = [1, 2, 3] li2 = li1.copy() li1.append(4) print(li1, li2) # [1, 2, 3, 4] [1, 2, 3] # 深拷贝 li1 = [1, 2, 3] li2 = copy.deepcopy(li1) li1.append(4) print(li1, li2) # [1, 2, 3, 4] [1, 2, 3]
多层的状况:
import copy # 浅拷贝 指向共有的地址 li1 = [1, 2, 3,[4,5],6] li2 = li1.copy() li1[3].append(7) print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6] # 深拷贝 重指向 li1 = [1, 2, 3,[4,5],6] li2 = copy.deepcopy(li1) li1[3].append(7) print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]
引用计数
标记清除
分代回收
可变数据类型:列表、字典、集合
不可变数据类型:数字、字符串、元组
1)
def a(): return [lambda x:i*x for i in range(4)] b=a() #返回个函数列表
print(b[1](1)) ---- 3 print(type(b),b) ---- print([m(1) for m in a()]) ---- [3,3,3,3] print([i*i for i in [1,2,3]]) ---- [1,4,9] #解释: 函数返回值为一个列表表达式,通过4次循环结果为包含四个lambda函数的列表, 因为函数未被调用,循环中的i值未被写入函数,通过屡次替代,循环结束后i值为3。
请修改a的定义来产生指望的结果(0,2,4,6)。 def a(): return (lambda x:i*x for i in range(4)) #返回一个生成器表达式 print([m(2) for m in a()])
2)
现有两个元组(('a'),('b')),(('c'),('d')),请使用python匿名函数生成列表[{'a':'c'},{'b':'d'}] #匿名函数形式: li1=(('a'),('b')) li2=(('c'),('d')) ret=map(lambda n:{n[0]:n[1]},zip(li1,li2)) print(list(ret)) #列表表达式形式: li1=(('a'),('b')) li2=(('c'),('d')) print([{n[0]:n[1]} for n in zip(li1,li2)])
v = dict.fromkeys(['k1', 'k2'], []) v['k1'].append(666) print(v) 结果: {'k1': [666], 'k2': [666]} 解释: Python 字典(Dictionary) fromkeys() 函数用于建立一个新字典,以序列seq中元素作字典的键,value为字典全部键对应的初始值,默认为None。 v1 = dict.fromkeys(['k1', 'k2']) print(v1) # {'k1': None, 'k2': None} v2 = dict.fromkeys(['k1', 'k2'], []) print(v2) # {'k1': [], 'k2': []}
返回数字的绝对值。
根据函数对指定序列作映射
map()函数接收两个参数,一个是函数,一个是可迭代对象,map将传入的函数依次做用到序列的每一个元素,并把结果做为新的list返回。
返回值:
Python2 返回列表
Python3 返回迭代器
例子1: def mul(x): return x*x n=[1,2,3,4,5] res=list(map(mul,n)) print(res) #[1, 4, 9, 16, 25]
例子2:abs() 返回数字的绝对值
ret = map(abs,[-1,-5,6,-7])
print(list(ret))
# [1, 5, 6, 7]
filter()函数接收一个函数 f(函数)和一个list(可迭代对象),这个函数 f的做用是对每一个元素进行判断,返回 True或 False, filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。 # 条件函数
def is_odd(x): return x % 2 == 1 v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17])) print(v) #[1, 7, 9, 17]
filter 与 map 总结
共同点: # 参数: 都是一个函数名 + 可迭代对象 # 返回值: 都是返回可迭代对象 区别: # filter 是作筛选的,结果仍是原来就在可迭代对象中的项 # map 是对可迭代对象中每一项作操做的,结果不必定是原来就在可迭代对象中的
isinstance() 函数来判断一个对象是不是一个已知的类型,相似 type()。 isinstance() 与 type() 区别: type() 不会认为子类是一种父类类型,不考虑继承关系。返回对象类型 isinstance() 会认为子类是一种父类类型,考虑继承关系。返回布尔
若是要判断两个类型是否相同推荐使用 isinstance()。 # 例
a = 2
print(isinstance(a,int)) # True
print(isinstance(a,str)) # False # type() 与 isinstance() 区别 class A: pass class B(A): pass print("isinstance",isinstance(A(),A)) # isinstance True print("type",type(A()) == A) # type True print('isinstance',isinstance(B(),A) ) # isinstance True print('type',type(B()) == A) # type False
zip打包函数, # 将对象中对应的元素打包成一个个元组, # 而后返回由这些元组组成的列表迭代器。 # 若是各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。 print(list(zip([0,1,3],[5,6,7],['a','b']))) # [(0, 5, 'a'), (1, 6, 'b')]
zip() 函数用于将可迭代的对象做为参数,将对象中对应的元素打包成一个个元组,而后返回由这些元组组成的列表。 >>>a = [1,2,3] >>> b = [4,5,6] >>> c = [4,5,6,7,8] >>> zipped = zip(a,b) # 打包为元组的列表 [(1, 4), (2, 5), (3, 6)] >>> zip(a,c) # 元素个数与最短的列表一致 [(1, 4), (2, 5), (3, 6)] >>> zip(*zipped) # 与 zip 相反,可理解为解压,返回二维矩阵式 [(1, 2, 3), (4, 5, 6)]
reduce()
''' reduce() 累计函数 reduce() 函数会对参数序列中元素进行累积 函数将一个数据集合(链表、元组等)中的全部数据进行下列操做 ''' 注意: Python3已经将reduce() 函数从全局名字空间里移除了,它如今被放置在 fucntools 模块里,若是想要使用它,则须要经过引入 functools 模块来调用 reduce() 函数: from functools import reduce def add(x,y): return x + y print(reduce(add,[1,2,3,4,5])) # 15 print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15 print(reduce(add,range(1,101))) # 5050
map:根据函数对指定序列作映射
map 参数 接收两个参数:一个是函数,一个是序列(可迭代对象) 返回值 Python2 返回列表 Python3 返回迭代器 # 例子: # abs() 函数返回数字的绝对值 # 新的内容的个数等于原内容的个数 # ret = map(abs,[-1,-5,6,-7]) # print(list(ret)) # [1, 5, 6, 7]
filter:过滤函数 新的内容少于等于原内容的时候。才能使用filter
filter() 函数用于过滤序列,过滤不符合条件的元素,返回由符合条件元素组成的心列表 参数: function 函数 iterable 可迭代对象 返回值: 返回列表 # 筛选大于10的数 def is_odd(x): if x>10: return True ret = filter(is_odd,[1,4,5,7,8,9,76]) # 为迭代器 print(list(ret)) # [76]
reduce:对于序列内全部元素进行累计操做
''' reduce() 函数 reduce() 函数会对参数序列中元素进行累积 函数将一个数据集合(链表、元组等)中的全部数据进行下列操做 ''' from functools import reduce def add(x,y): return x + y print(reduce(add,[1,2,3,4,5])) # 15 print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15 print(reduce(add,range(1,101))) # 505
multi = '\n'.join([' '.join(['%s*%s=%2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)])
print(multi)
提示:核心是两层嵌套列表生成式--> [[... for ...] for ...],而后用空格去拼接内层列表元素,再用换行去拼接外层列表元素。
1:pip包管理器 2:源码下载 -下载 -解压 -python setup.py build -python setup.py install
用过的第三方模块:pymysql,BeautifulSoup,SQLAlchemy,Scrapy,Django,memcached等。
re,os,sys,json,time,datetime,random,logging等。
re.match 尝试从字符串的起始位置匹配一个模式,若是不是起始位置匹配成功的话,match()就返回none。
re.search 扫描整个字符串并返回第一个成功的匹配。
匹配一个字符串没有节制,能匹配多少就去匹配多少,知道没有匹配的为止。
a. [ i % 2 for i in range(10) ]
print([ i % 2 for i in range(10) ]) # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] print([ i for i in range(10) ]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print([ 10 % 2]) # [0] # %是个取余数运算符。
b. ( i % 2 for i in range(10) )
print(( i % 2 for i in range(10) )) # <generator object <genexpr> at 0x00000000020CEEB8> 生成器 # 在Python中,有一种自定义迭代器的方式,称为生成器(Generator)。 # 定义生成器的两种方式: # 1.建立一个generator,只要把一个列表生成式的[]改为(),就建立了一个generator: # generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,
没有更多的元素时,抛出StopIteration的错误。 # 2.定义generator的另外一种方法。若是一个函数定义中包含yield关键字,那么这个函数就再也不是一个普通函数,
而是一个generator
a. 1 or 2
b. 1 and 2
c. 1 < (2==2)
d. 1 < 2 == 2
>>> 1 or 2 1 >>> 1 and 2 2 >>> 1 < (2==2) False >>> 1 < 2 == 2 True
def func(a,b = []): b.append(1) print(a,b) func(a=2) func(2) func(2) ''' 2 [1] 2 [1, 1] 2 [1, 1, 1] 函数的默认参数是一个list 当第一次执行的时候实例化了一个list 第二次执行仍是用第一次执行的时候实例化的地址存储 因此三次执行的结果就是 [1, 1, 1] 想每次执行只输出[1] ,默认参数应该设置为None,而后初始化b=[] '''
list("1,2,3".split(','))
[int(x) for x in ['1','2','3']]
a等于b,a不等于c
补充:
a=[1,2,3,4,5],b=a和b=a[:],有区别么? a = [1,2,3,4,5] b = a b1 = a[:] print(b) # [1, 2, 3, 4, 5] b.append(6) print("a",a) # a [1, 2, 3, 4, 5, 6] print("b",b) # b [1, 2, 3, 4, 5, 6] 传递引用 print("b1",b1) # b1 [1, 2, 3, 4, 5] 拷贝
[i*i for i in range(1,11)]
list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))
python中的global语句是被用来声明全局变量的。
x = 2 def func(): global x # global用于函数中 x = 1 return x func() print(x) # 1
logging 模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。 做用:能够了解程序运行状况,是否正常
在程序的出现故障快速定位出错地方及故障分析
# 实现一个栈stack,后进先出 ''' class Stack: def __init__(self): self.items = [] def is_empty(self): # 判断是否为空 return self.items == [] def push(self,item): # 加入元素 self.items.append(item) def pop(self): # 弹出元素 return self.items.pop() def peek(self): # 返回栈顶元素 return self.items[len(self.items)-1] def size(self): # 返回栈的大小 return len(self.items) if __name__ == "__main__": stack = Stack() stack.push("H") stack.push("E") stack.push("L") print(stack.size()) # 3 print(stack.peek()) # L print(stack.pop()) # L print(stack.pop()) # E print(stack.pop()) # H '''
1.占位符%
%d 表示那个位置是整数;%f 表示浮点数;%s 表示字符串。
print('Hello,%s' % 'Python') print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:Hello,666Python10.00
2.format
print('{k} is {v}'.format(k='python', v='easy')) # 经过关键字 print('{0} is {1}'.format('python', 'easy')) # 经过关键字
含有__iter__和__next__方法 (包含__next__方法的可迭代对象就是迭代器)
包括含有yield这个关键字,生成器也是迭代器,调动next把函数变成迭代器。
应用场景: range/xrange - py2:xrange(1000000) 生成器 - py3:range(1000000)生成器
- redis获取值
conn = Redis(...)
def hscan_iter(self, name, match=None, count=None):
"""
Make an iterator using the HSCAN command so that the client doesn't
need to remember the cursor position.
``match`` allows for filtering the keys by pattern
``count`` allows for hint the minimum number of returns
"""
cursor = '0'
while cursor != 0:
# 去redis中获取数据:12
# cursor,下一次取的位置
# data:本地获取的12条数数据
cursor, data = self.hscan(name, cursor=cursor,match=match, count=count)
for item in data.items():
yield item
一个类内部实现__iter__方法且返回一个迭代器。
装饰器: 可以在不修改原函数代码的基础上,在执行先后进行定制操做,闭包函数的一种应用。 场景: - flask路由系统 - flask before_request - csrf - django内置认证 - django缓存 # 手写装饰器; import functools def wrapper(func): @functools.wraps(func) #不改变原函数属性 def inner(*args, **kwargs): 执行函数前 return func(*args, **kwargs) 执行函数后 return inner 1. 执行wapper函数,并将被装饰的函数当作参数。 wapper(index) 2. 将第一步的返回值,从新赋值给 新index = wapper(老index) @wrapper #index=wrapper(index) def index(x): return x+100
调用装饰器实际上是一个闭包函数,为其余函数添加附加功能,不修改被修改的源代码和不修改被修饰的方式,装饰器的返回值也是一个函数对象。
好比:插入日志、性能测试、事物处理、缓存、权限验证等,有了装饰器,就能够抽离出大量与函数功能自己无关的雷同代码并继续重用。
二分查找算法:简单的说,就是将一个列表先排序好,好比按照从小到大的顺序排列好,当给定一个数据,好比3,查找3在列表中的位置时,能够先找到列表中间的数li[middle]和3进行比较,当它比3小时,那么3必定是在列表的右边,反之,则3在列表的左边,好比它比3小,则下次就能够只比较[middle+1, end]的数,继续使用二分法,将它一分为二,直到找到3这个数返回或者列表所有遍历完成(3不在列表中)
优势:效率高,时间复杂度为O(logN);
缺点:数据要是有序的,顺序存储。
li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def bin_search(arr, find):
mid = len(arr) // 2
if len(arr) >= 1:
if find < arr[mid]:
bin_search(arr[:mid], find)
elif find > arr[mid]:
bin_search(arr[mid + 1:], find)
else:
# return mid # 当心这个坑!递归中不能用return!!
print(mid)
else:
# return '-1' # 当心这个坑!递归中不能用return!!
print("not found !")
ef foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >>>bar = foo() >>>bar() 12
说明:
bar在foo函数的代码块中定义。咱们称bar是foo的内部函数。
在bar的局部做用域中能够直接访问foo局部做用域中定义的m、n变量。
简单的说,这种内部函数可使用外部函数变量的行为,就叫闭包。
os模块 负责程序与操做系统的交互,提供了访问操做系统底层的接口。
sys模块 负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
#********************** os内置模块 **********************#
os.name 查看当前操做系统的名称。windows平台下返回"nt",Linux则返回"posix"
os.curdir 等价于".",表示当前目录
os.pardir 等价于"..",表示上级目录
os.getcwd() 取当前工做目录名
os.chdir() 切换工做目录,至关于shell下的cd
os.chmod() 改变目录权限
os.rename('oldname', 'newname') 重命名文件
os.walk() 生成目录树下的全部文件名
os.mkdir/makedirs('dirname') 建立目录/多层目录
os.rmdir/removedirs('dirname') 删除目录/多层目录
os.remove('path/filename') 删除文件
os.listdir('dirname') 列出指定目录的文件
os.path.basename('path/filename') 去掉目录,返回文件名
os.path.dirname('path/filename') 去掉文件名,返回目录
os.path.join(path1[,path2[,...]]) 将分离的各部分组拼接成一个路径名
os.path.split('path/filename') 返回(dirname(), basename())元组
os.path.splitext('path/filename') 返回(filename, '.扩展名')元组
os.path.getatime/ctime/mtime() 分别返回最近访问、建立、修改时间(时间戳)
os.path.getsize('path/filename') 返回文件大小(字符数)
os.path.exists() 是否存在
os.path.isabs() 是否为绝对路径
os.path.isdir() 是否为目录
os.path.isfile() 是否为文件
#********************** sys内置模块 **********************#
sys.argv 命令行参数List,第一个元素是程序自己路径
sys.hexversion 获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version 获取Python解释程序的版本信息
sys.maxsize 最大的Int值
sys.maxunicode 最大的Unicode值
sys.modules 返回系统导入的模块字段,key是模块名,value是模块
sys.path 返回模块的搜索路径,初始化时使用'PYTHONPATH'环境变量的值
sys.platform 返回操做系统平台名称
sys.exec_prefix 返回平台独立的python文件安装的位置
sys.byteorder 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
sys.copyright 记录python版权相关的东西
sys.api_version 解释器的C的API版本
sys.stdin 标准输入
sys.stdout 标准输出
sys.stderr 错误输出
sys.modules.keys() 返回全部已经导入的模块列表
sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) 退出程序,正常退出时exit(0)
sys.exc_clear() 用来清除当前线程所出现的当前的或最近的错误信息
sys.stdin input()调用了sys.stdin.read()
sys.stdout write()调用了sys.stdout.write()
sys.stderr
import random print(random.random()) # 用于生成一个0到1的随机浮点数: 0 <= n < 1.0 print(random.randint(1, 1000)) # 用于生成一个指定范围内的整数
print(random.uniform(1, 1000)) # 用于生成一个指定范围内的浮点数
os.remove(file) # 删除文件
os.rmdir(dir) # 删除目录
面对对象是一种编程思想,以类的眼光来来看待事物的一种方式。将有共同的属性和方法的事物封装到同一个类下面。
继承:将多个类的共同属性和方法封装到一个父类下面,而后在用这些类来继承这个类的属性和方法。
封装:将有共同的属性和方法封装到同一个类下面。
多态:Python天生是支持多态的。指的是基类的同一个方法在不一样的派生类中有着不一样的功能(重写体现了多态)。
继承概念的实现方式主要有2类:直接继承、接口继承。 直接继承是指使用基类的属性和方法而无需额外编码的能力; 接口继承是指仅使用属性和方法的名称、可是子类必须提供实现的能力(子类重构父类方法); python 两种类:经典类 新式类 python3 新式类 都默认继承object python2 经典类和新式类 并存 class Animal: 经典类 -- 继承顺序 个别使用方法 class Animal(object): 新式类 继承分为单继承和多继承 Python是支持多继承的。 若是没有指定基类,python的类会默认继承object类,object是全部python类的基类,它提供了一些常见方法(如__str__)的实现。
补充继承的应用
一、对象能够调用本身本类和父类的全部方法和属性, 先调用本身的 本身没有才调父类的。谁(对象)调用方法,方法中的self就指向谁 class Foo: def __init__(self): self.func() def func(self): print('Foo.func') class Son(Foo): def func(self): print('Son.func') s = Son() # Son.func ======================================================== class A: def get(self): self.say() def say(self): print('AAAAA') class B(A): def say(self): print('BBBBB') b = B() b.get() #输出结果为:BBBBB
Python的类能够继承多个类,Python的类若是继承了多个类,那么其寻找方法的方式有两种: 当类是经典类时,多继承状况下,会按照深度优先方式查找 --py2 当类是新式类时,多继承状况下,会按照广度优先方式查找 --py3 简单点说就是:经典类是纵向查找,新式类是横向查找。 经典类和新式类的区别就是,在声明类的时候,新式类须要加上object关键字。在python3中默认全是新式类。
用于子类继承父类的方法,会将父类的方法彻底继承下来。
class Foo():
def bar(self):
print('from parent class.')
class Child(Foo):
def bar(self):
super(Child, self).bar() # 继承了父类的方法
print('from child class.') # 增长了本身的功能
c = Child()
c.bar()
# 结果:
from parent class.
from child class.
用于保护装饰器传入的函数。
import functools def deco(func): @functools.wraps(func) # 加在最内层函数正上方 def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper @deco def index(): '''哈哈哈哈''' x = 10 print('from index') print(index.__name__) print(index.__doc__) # 加@functools.wraps # index # 哈哈哈哈 # 不加@functools.wraps # wrapper # None
__call__:实例对象加( )会执行def __call__:... 方法里边的内容。
__del__:析构方法,当对象在内存中被释放时,自动触发执行。如当 del obj 或者应用程序运行完毕时,执行该方法里边的内容。
__enter__和__exit__:出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量;with中代码块执行完毕时执行__exit__里边的内容。
__module__:表示当前操做的对象在那个模块 obj.__module__
__class__ :表示当前操做的对象的类是什么 obj.__class__
__doc__:类的描述信息,该描述信息没法被继承
__str__:改变对象的字符串显示 print函数 --->obj.__str__()
__repr__:改变对象的字符串显示 交互式解释器 --->obj.__repr__()
__format__:自定制格式化字符串
__slots__:一个类变量 用来限制实例能够添加的属性的数量和类型
__setitem__,__getitem,__delitem__:
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
__setattr__,__delattr__,__getattr__
看他的调用者是谁,若是是类,就须要传入一个参数self的值,这时他就是一个函数,
若是调用者是对象,就不须要给self传入参数值,这时他就是一个方法
print(isinstance(obj.func, FunctionType)) # False
print(isinstance(obj.func, MethodType)) # True
尽管 classmethod 和 staticmethod 很是类似,但在用法上依然有一些明显的区别。classmethod 必须有一个指向类对象的引用做为第一个参数cls,而 staticmethod 能够没有任何参数。
举个栗子:
class Num: # 普通方法:能用Num调用而不能用实例化对象调用 def one(): print('1') # 实例方法:能用实例化对象调用而不能用Num调用 def two(self): print('2') # 静态方法:能用Num和实例化对象调用 @staticmethod def three(): print('3') # 类方法:第一个参数cls长什么样不重要,都是指Num类自己,调用时将Num类做为对象隐式地传入方法 @classmethod def go(cls): cls.three() Num.one() #1 #Num.two() #TypeError: two() missing 1 required positional argument: 'self' Num.three() #3 Num.go() #3 i=Num() #i.one() #TypeError: one() takes 0 positional arguments but 1 was given i.two() #2 i.three() #3 i.go() #3
__call__ __new__ __init__ __doc__ __class__ __del__ __dict__ __str__
60个(A35)。
题意理解:组成后的数值不相同,且组合的三个位数之间数字不重复。
使用python内置的排列组合函数(不放回抽样排列)
product 笛卡尔积 (有放回抽样排列)
permutations 排列 (不放回抽样排列)
combinations 组合,没有重复 (不放回抽样组合)
combinations_with_replacement 组合,有重复 (有放回抽样组合)
import itertools print(len(list(itertools.permutations('12345', 3)))) # 60
反射的核心本质就是以字符串的形式去导入个模块,利用字符串的形式去执行函数。 Django中的CBV就是基于反射实现的。
metaclass用来指定类是由谁建立的。
类的metaclass默认是type。咱们也能够指定类的metaclass值。在python3中:
class MyType(type): # 传入type def __call__(self, *args, **kwargs): return 'MyType' class Foo(object, metaclass=MyType): def __init__(self): return 'init' def __new__(cls, *args, **kwargs): return cls.__init__(cls) def __call__(self, *args, **kwargs): return 'call' obj = Foo() print(obj) # MyType
1:使用模块 Python的模块就是自然的单例模式。 由于模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。 所以,咱们只需把相关的函数和数据定义在一个模块中,就能够得到一个单例对象了。 例如:
class Single(object): def foo(self): pass single = Single() # 实例好一个对象
将上面代码保存在文件test.py,要使用时,直接在其余文件中导入此文件中的对象,这个对象就是单例模式的对象. 如:from test import single
2:使用装饰器
def single(cls):
_instance = {}
def _singlewrap(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return _singlewrap
@single
class A(object):
def __init__(self, x=0):
self.x = x
a1 = A(1)
a2 = A(2)
print(a1 == a2) # True
3:基于__new__方法(推荐)
当咱们实例化一个对象时,是先执行了类的__new__方法,咱们没写时,默认调用object.__new__,实例化对象;而后再执行类的__init__方法,对这个对象进行初始化,全部咱们能够基于这个,实现单例模式。
例:
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'instance'):
cls.instance = super().__new__(cls)
return cls.instance
a = Person('p1',21)
b = Person('p2',22)
print(a == b, a.name == b.name)
# 这里的打印结果都是True,可见 a 和 b 都是同一个实例(实例 b 覆盖了实例 a)。
# 单例做用:
#第1、控制资源的使用,经过线程同步来控制资源的并发访问;
#第2、控制实例产生的数量,达到节约资源的目的;
#第3、做为通讯媒介使用,也就是数据共享。好比,数据库链接池的设计通常采用单例模式,数据库链接是一种数据库资源。
# 应用场景:
含义:装饰器本质就是函数,为其余函数添加附加功能。
原则:
不修改被修饰函数的代码;
不修改被修饰函数的调用方式。
应用场景:
无参装饰器在用户登陆认证中常见
有参装饰器在flask的路由系统中见到过
import functools def wrapper(func): @functools.wraps(func) def inner(*args, **kwargs): print('我是装饰器') return func return inner @wrapper def index(): print('我是被装饰函数') return None
# 应用场景 - 高阶函数 - 闭包
# 捕获异常 def temp_convert(var): try: return int(var) except ValueError as Argument: print ("参数没有包含数字%s"%Argument) # 调用函数 temp_convert("xyz") # 以10为基数的int()的无效文字:“xyz”
---------------------------------------------------------------------------- # raise语法 #raise [Exception(args [,traceback])] # 语句中Exception是异常的类型,args是自已提供的异常参数。 class Networkerror(RuntimeError): def __init__(self, arg): self.args = arg try: raise Networkerror("Bad hostname") except Networkerror as e: print(e.args)
mro就是方法解析顺序,表明了类继承的顺序。经典类在多重继承时采用深度优先原则,而新式类是采用广度优先的原则。
isinstance(对象,类) 判断这个对象是否是这个类或者这个类的子类的实例。
# 判断a 属不属于A这个类(能够判断到祖宗类) class A: pass class B(A): pass
a = A() b = B() print(isinstance(b,A)) # ===> True 判断到祖宗类 # 任何与object都是True,内部都继承object class A:pass a = A() # 实例化 print(isinstance(a,object)) # True
应用场景:rest framework 认证的流程
scrapy-redis
Given an array of integers, return indices of the two numbers such that they add up to a
specific target.You may assume that each input would have exactly one solution, and you may
not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
支持几乎除了集合和日期以外的Python对象。
# json模块不支持datetime序列化,须要自定义格式类
class ComplexEncoder(json.JSONEncoder): # 继承JSONEncoder def default(self, obj): # 重写方法 if isinstance(obj, datetime): return obj.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(obj, date): return obj.strftime('%Y-%m-%d') else: return super().default(self, obj) # 返回父类方法 print(json.dumps({'now': datetime.now()}, cls=ComplexEncoder))
在 dumps 函数中添加参数 ensure_ascii=False 便可解决。
语法:assert '条件', '提示'
其中,若"条件"为真,程序继续执行;若"条件"为假,程序终止,并给出"提示"。
用于程序的调试。
上下文管理器:在正常处理系统资源(文件、线程锁和链接)以前须要先执行一些准备动做,及其以后须要继续执行一些收尾动做。
例如:当须要操做文件或数据库的时候,首先须要获取文件句柄或者数据库链接对象,当执行完相应的操做后,须要执行释放文件句柄或者关闭数据库链接的动做。
又如,当多线程程序须要访问临界资源的时候,线程首先须要获取互斥锁,当执行完成并准备退出临界区的时候,须要释放互斥锁。
os.listdir() ----列出当前目录和文件
os.walk() ----递归列出全部文件