python学习(更新中)
- tuple类型判断 type() a = (1) 为int类型 b = () 为tuple类型 c = ([1,2,3],4) tuple类型不可改变,但是通过 c[0][0] = 111 方式可以改变 - input()获取的为string,可能需要int()转换对比 - dist字典对象,key必须不可变,即key不能为list - print(‘1’,2,3,sep=‘+’) // 1+2+3 sep分隔 - print('1',2,3,end=';') // 1 2 3; end分隔 - 逻辑运算符 - an or not 与 或 非 - 成员运算符 - in 、not in //a = [1,2,3]; 1 in a;//true; 5 not in a //true - 身份运算符,身份表达式 - python中变量有三种属性:name、id、value,变量名、内存地址、变量值 - a = [1,2,3] b = [1,2,3] // a == b //true; a is b //false; c = a; c is a //true c ==a //true; c = [2,4,5]; c==a //false; c is a //false - 运算符优先级 (python有13级,1级最高,13最低) - a = (b=c) //执行顺序从右向左赋值 - 先乘除后加减 - a=b=c=d=e=1;//1 1 1 1 1; c =3; // 1 1 3 1 1; - python2中1 <> 2 //true python3中会直接报错 - -5~256之间的262个整数===> a = 2;b=2;a is b//true; a = 267;b=267;a is b //false - == 为比较;is 为判断同一性,即判断id是否相等;查看变量id的方法为:a = 1;id(a);===>可以理解为is判断的是id,==判断的是value是否相等 ## 条件语句 - if elif else - switch语法 switch(key){ case case1: something; break; default: something; } - - from __future__ import division x = 1; y = 2; operator = '/' result = { '+' : x + y, '-' : x - y, '*' : x * y, '/' : x / y } # print(result.get(operator)) # print(result.get('/')) # print(result['/']) // js function isLen(str){ return [4,6][(str.length>6)*1] } isLen('ssssss') js的 ==>布尔*1才能转数值 // py==> [1,2][False] def isLen(str): return [4,7][len(str)>6] //循环 - range(start,end,step) 为range(20),range(4,10),range(2,10,2)//偶数[2, 4, 6, 8] fruits = ['banana','apple','mango'] //第一种 for i in range(len(fruits)): print(fruits[i]) //第二种 for i in fruits: print(i) //第三种 for i,e in enumerate(fruits): print(i,e) - 注意:i,e 和(i,e) 的性能测试区分为,前者适合在200条以上,后者适合200以内 - for else for num in range(10,20): for i in range(2,num): # continue print('第一种为:'+str(i)) else: # continue print('第二种为:'+str(num)) //10-19 - 循环语句控制 ==> continue、pass、break for i in range(2): print(i) i+=7 print(i) // 0 7 1 8 // 与js差别挺大 js 为 0 7 ## 列表 - ‘abc'.title() //Abc int类型会报错 - 合理运用切片[1,2,3][:2]//12 - insert(index,obj) //按索引插入 - append(obj)//末尾追加 - del删除元素 del a[len(a)-1] //删除a列表最后一个 - a.pop() 删除最后一个元素,a.pop(index)//删除对应索引的元素 - a.remove(obj)//删除对应元素,根据值删除,如果该值不存在会报错 - a.sort(function) //排序 a.sort(reverse=True)//逆序 ===>sort排序会改变列表如果仅仅临时获取可以使用sorted(list) - 倒序a.reverse() ===>与sort系列不同的是,仅是翻转并不进行排序 - len(list) //获取list长度 - [1]+[2] //[1,2] - [1]*5 //[1,1,1,1,1] - 1 in a //判断1是否存在于a中 - for x in a:print(x) //遍历列表 - max(list) //获取最大值 min(list)//获取最小值 - list.extend(otherlist) //向list中追加所有otherlist的内容,与list+otherlist 不一样的是会后者只是临时数据,而extend会改变list的数据 - list.clear() // [] - list=other.copy() // python注意指向,赋值后改变other的数据,list依然为赋值时的数据 - list.index(obj) //获取obj的索引 ## Tuple - tuple不可以改变其内的元素 - tuple[0]、tuple[:3] ==>读取方式和list几乎一样 - 遍历同样为for in方式 - len - (1,2)+(3,4) //(1,2,3,4) - (1,2)*5 - 1 in a - del tuple //此时输入tuple提示未定义,list删除后为 [] - min,max - tuple(other) //强转,如果int、bool类型会报错==>未一一尝试 ## 字段dict - a={‘a’:1,’b’:2}//key value键值对,key只能为字符串类型 a.get(‘a’)//获取value; 或者 a[‘a’] ; ===>需要注意的是这里不支持a.a方式 - a[‘c’] = 4 //向字典a中添加数据 ==>修改也是这个操作 - del a[‘c’] //删除 , 或者直接 del a 删除a这个字典 - len(dist) - str(dist) // "{'b': 2, 'c': 4}" - type(dist) //这个是py里面查看类型的方法 - for key,value in a.items():print(key,value) //遍历字典 - dist.keys() //dict_keys(['b', 'c’]). for name in dist.keys() 等同于 for name in dist - dist.values() //dict_values([2, 4]). - dist.clear() //清除后为{} - dist.copy() - dist.get(key) //获取值 - dist.setdefault('c','mokong’) //如果c不存在于dict中,则新建一个key,并赋值为第二个参数的’mokong’,如果无第二个参数则赋值为None - dist.update(newdict) //将newdict中的数据加入到dict中,无冲突则追加;如果key相同则newdict的value覆盖 - 坑点 key = ('Google', 'Runoob', 'Taobao') value = ['1', '2', '3'] dict = dict.fromkeys(key,value) print("新字典为 : %s" % str(dict)) //{'Google': ['1', '2', '3'], 'Runoob': ['1', '2', '3'], 'Taobao': ['1', '2', '3']} dict['Google'].append('hhh') print("新字典为 : %s" % str(dict)) // {'Google': ['1', '2', '3', 'hhh'], 'Runoob': ['1', '2', '3', 'hhh'], 'Taobao': ['1', '2', '3', 'hhh’]} ### 集合 ,无序不重复 - 空集合创建需要使用set(),而不是 直接{} - | 、& 、- 、^ 并集、交集、差集、不同时存在的元素 - 常见类型转换 - int() 、 float、str、eval、tuple、list、set、dict、frozenset({*转为不可变集合,可以为一个dict、list...等等*}) - ## 函数 - def test(str=1):print(str);test('2’) //如果是def test(str)的话直接test()会报错 def pr(a, *b): print(a) for i in b: print('这里会输出啥?:',i) return pr(1) pr(2,3,4) # 1 # 2 # 这里会输出啥?: 3 # 这里会输出啥?: 4 - 上面使用的是不定长参数 - 值传递和引用传递参数 list = [1, 2, 3] def app(arr): arr.append(4) app(list) print(list) - 值传递的贝雕函数的形参作为被调用函数的局部变量来处理,在栈中开辟了内存空间来存放放进来的实参的值,所以不会印象主函数的实参 - 引用传递被调函数的形参虽然也是作为局部变量在堆栈中开辟了内存空间,但是此时存放的是有主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成简洁寻址,即通过堆栈总存放的地址访问主调函数中的实参变量。 - 网上有个形象的解释理解:你有一把钥匙,如果你直接将这个钥匙借给了别人,那么别人刻字或者其他操作后,返还给你的钥匙就会有他人的刻字;这个就是“引用传递”;同理,你有一把钥匙,复制了一份给别人了,那么别人刻字啥的你的钥匙还是不会受到影响~这就是值传递~ ### 函数作用域 - py有三种作用域:局部作用域、全局作用域、内置作用域 - 每执行一个py函数都会创建一个新的命名空间,即新的局部作用域 a = 1 def fn(): # global a a = 0 a += 3 # a.append('5') print('里面', a) // a = [1,2] print('外面执行前',a) fn() print('外面执行后',a) // 变量为1时:未开启global a时为:1、3、1 ,开启后为:1 、 3 、 3 //变量为list时为:[1,2] 、 [1,2,5] 、 [1,2,5] - import 方式导入变量如果是str或者整数等单个值,则无论是global或者传参方式都不会改变到主调函数的实参;而list等其他如果参数传递,则会修改主调函数的实参 - form module_name import function_name as alias //设置别名 - from module_name import * //导入所有方法,不用module_name.function_name方式调用 ## 面向对象 ### 类对象 class mc: i = 999 def fn(self): print(self.i + 1) print("hhh") x = mc() x.fn() //10000 hhh print(x.i) //999 - 类方法的第一个参数必须为self,且不能省略(其实只是一个实参,可以写成this~) - __init__构造方法,用于实例化基础数据 - 在类方法前加两个下横线则归位私有,类外不可以调用def __fn():,私有属性也是在前面加两个__在外部无法调用,除非通过内部方法 - 类中的方法可分为实例方法、类方法、静态方法:==>mc = class_name();mc.fn() //此为实例方法;类方法声明时需要在上一行加@classmethod,而且参数必须有默认参数cls;静态方法声明需要在上一行添加@staticmethod无默认参数;===>类方法和静态方法调用时都是直接class_name.fn()方式直接调用 class Base: def __init__(self, name, age): self.name = name self.age = age self.__area = "上海" def info(self): print("我是:", self.name, "今年:", self.age, "坐标", self.__area) class kz(Base): def __init__(self, name, age): # 经典类写法 # Base.__init__(self, name, age) # 新式类的写法 super().__init__(name, age) self.__job = "it" def info_kz(self): print(self.__job) class child(kz): def __init__(self, name, age, other_size=60): super().__init__(name, age) self.ss = "这是啥啊" self.Other = Other(other_size) # def print_pra(self): # print("私有属性能输出吗?不能", self.__job) class Other(child): def __init__(self, other_size=69): self.other_size = other_size def des(self): print("其他参数为:", self.other_size) myClass = child("jack", "20") myClass.info() myClass.info_kz() myClass.print_pra() myClass.Other.des() print(myClass.ss) //我是: jack 今年: 20 坐标 上海 //it //私有属性能输出吗?不能 1 //其他参数为: 60 //这是啥啊 - 类不可以互相调用私有属性和方法 - 子类方法名重复会覆盖父类方法,多继承方法重复会以最先继承的为主 ## 面向对象 - 类:就是具有相同属性和功能的对象的集合。用来描述具有相同的属性的方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是累的实例 - 类变量:类变量在整个实例化的对象中是公用的。类变量定义在泪中且在函数题之外。类变量通常不作为实例变量使用 - 方法:在类中定义的函数 - 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法 - 构造方法:负责对类进行初始化 - 数据成员:类变量或者实例变量用于处理类及其实例对象的相关数据 - 方法重写:也叫方法重载,如果从父类继承的方法不能满足子类的需求可以对其进行改写,这个过程叫方法的覆盖,也叫方法的重写 - 实例变量:定义在方法中的变量,只作用于当前实例的类 - 属性:适合于以字段的方式使用方法调用的场合,这里字段是存储类要满足其设计所需要的数据 - 封装:每个对象都包含他能进行操作的所有信息。封装可以坚持少耦合,类的内部可以修改,可以使类具有清晰的对外接口 - 继承:如果子类继承父类,则子类具有父类的一些属性和功能。即一个派生类,子类继承基类(父类)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待 - 实例化:创建一个类的实例,类的具体对象 - python可以理解为万事万物皆对象….(好熟悉的说法…..) - uml图,建模语言? ## 使用包 - form package import item //item既可以是子模块(子包)也可以是报厘米啊你定义的其他名称比如函数、类和变量,注意:包的目录中只有含有__init__.py这个文件的时候才会被认为是包,这个文件可以为空 from moudle.info import echo, ant print(ant) echo() - 使用其他包的方式 class extend(Car): def __init__(self, manufacturer, model, year): super().__init__(manufacturer, model, year) self.battery = Battery() self.children = Children() ## 迭代器 - 注意!!!:python的函数中和全局同名的变量,如果有修改变量的值就会变成局部变量;如果确定要引用全局变量,并且要对他进行修改,必须加上global关键字 x = 1 def sup(): global x x+=2 - 扩充了解itertoos工具库:无穷迭代器、根据最短输入学历呃长度停止的迭代器、排列组合迭代器 ##生成器 def shengYield(n): while n > 0: print("开始生成:") yield n print("完成一次") n -= 1 if __name__ == "__main__": for n in shengYield(4): print("值为:", n) sheng_yield = shengYield(3) print("实例化了") sheng_yield.__next__() print("第二次") sheng_yield.__next__() - 上面的执行机制是,一次调用结束,就会立马停止:实例化了、开始生成;然后一直到再次执行next才会输出“完成一次” ## 装饰器 def deco(func): def _echo(a, b): print("在函数myfunc()之前被调用") ret = func(a, b) print("再函数myfunc之后被调用,结果是:%s" % ret) return ret return _echo @deco def myfunc(a, b): print("函数myfunc(%s,%s)被调用" % (a, b)) return a + b myfunc(1, 2) //在函数myfunc()之前被调用 ==>"函数myfunc(1,2)被调用 ==>"再函数myfunc之后被调用,结果是:3 ## 命名空间 - 每个函数都有自己的命名空间,叫做局部命名空间,它记录了函数的变量,包括函数的参数和局部定义的变量 - 每个模块拥有的自己的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、类、其他导入的模块、模块级的常量和变量 - 还有内置命名空间、任何模块均可访问他,它存放内置的函数和异常 - python搜索一个标识符的顺序是:legb - l(local)标示在一个函数定义中,而且在这个函数里面没有包含函数的定义 - e(enclosing function)表示在一个函数定义中,而且在这个函数里面没有在包含函数的定义 - g(global)是指一个模块的命名空间,也就是说,在一个。py文件中定义的标识符,但不在一个函数中 - b(builtin)是指python解释器启动时就已经具有的命名空间。之所以叫builtin是因为py解释器在启动时会自动载入__builtin__模块,在这个模块中的list、str等内置函数处于b层的命名空间中 i = 1 def fn(): global i //此处如果不加则下一行会报错, i += 1 a = 2 locals()["a"] = 3 print(locals()) //{a:2} globals()["i"] = 6 print(globals()) // {I:6} fn()
prices = {
"AAPL": 191.88,
"GOOG": 1186.96,
"IBM": 149.24,
"ORCL": 48.44,
"ACN": 166.89,
"FB": 208.09,
"SYMC": 21.29,
}
# 用股票价格大于100元的股票构造一个新的字典
prices2 = {key: value for key, value in prices.items() if value > 100}
# result:{'AAPL': 191.88, 'GOOG': 1186.96, 'IBM': 149.24, 'ACN': 166.89, 'FB': 208.09}
# 数组 最前面的部分(round(value+222,2))是列表生成元素表达式,可以是有返回值的函数
# 可以尝试key for key,value 最后数组返回的结果会是符合条件的key值,意思就是指定返回参数,可以是参数或者有返回值的函数
prices2 = [round(value + 222, 2) for key, value in prices.items() if value > 100]
# result:['413.88, 1408.96, 371.24, 388.89, 430.09]
prices2 = [key for key, value in prices.items() if value > 100]
# result:['AAPL', 'GOOG', 'IBM', 'ACN', 'FB']
def test():
return 222
prices2 = [test() for key, value in prices.items() if value > 100]
# result:[222, 222, 222, 222, 222]
["%02d:%02d" % (h, m) for h in range(0, 24) for m in range(0, 60, 5)]
# result:['00:00', '00:05', '00:10', '00:15'...'23:45', '23:50', '23:55']
list = [[1,2,3],[4,5,6],[7,8,9]]
[row[2] for row in list]
# result:[3, 6, 9]
M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[M[i][i] for i in range(len(M))]
# result:[1, 5, 9]
bob = {'pay': 3000, 'job': 'dev', 'age': 42, 'name': 'Bob Smith'}
sue = {'pay': 4000, 'job': 'hdw', 'age': 45, 'name': 'Sue Jones'}
people = [bob, sue]
result = [ob['age']+100 if ob['age'] > 42 else ob['age'] for ob in people]
# result: [42,145]
mcase = {'a': 10, 'b': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
# result: {10: 'a', 34: 'b'}