基础语法 1 数据类型 1.1 基本类型 1.1.1 数字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 a = bin (16 ) b = oct (16 ) c = hex (16 ) type (a) d = int (a, 2 ) e = int (b, 8 ) f = int (c, 16 ) (0.1 + 0.2 ) == 0.3 0.1 + 0.2 b = round (0.3 , 1 ) print (b) 2 +1j
数据运算:
整数与浮点数的运算结果是浮点数。
除法运算的结果是浮点数。(8/4 = 2.0)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 (1 +3 -4 *2 )/5 2 **3 13 //5 13 %5 abs (-5 ) abs (3 +4j ) pow (2 , 5 ) pow (2 , 5 , 3 ) a = 1.618 print (round (a)) print (round (a, 2 )) print (round (a, 5 )) divmod (13 , 5 ) a = [...] max (a)min (a)a = [...] sum (a)
1.1.2 字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 "abc 123 @ 666" 'abc 123 @ 666' print ("\"python\" is good" )s = "py\ thon" print (s) a = "my name is peppa pig" print (a[0 ]) print (a[2 ]) print (a[5 ]) print (a[-1 ]) s = "python" print (s[0 :3 :1 ]) print (s[0 :3 ]) print (s[0 :3 :2 ]) print (s[:6 ]) print (s[:]) print (s[-6 :]) s = "123456789" print (s[-1 :-10 :-1 ]) print (s[:-10 :-1 ]) print (s[::-1 ]) a = "..." b = "..." c = a + b print (c*3 )str = "aaa bbb ccc" "aaa" in str for s in "python" : print (s) s = "python" len (s) print (ord ("1" )) print (chr (1010 )) str = "a b c d" str_list = str .split(" " ) s = "12345" s_join = "*" .join(s) s = " abc " print (s.strip(" " )) print (s.lstrip(" " )) print (s.rstrip(" " )) s = "python is good" s1 = s.replace("python" ,"py" ) print (s1) s = "python is an excellent language" print (s.count("an" )) s.upper() s.lower() s.title()
1.1.3 布尔 1 2 3 4 5 6 7 8 9 x = 2 < 1 print (any ([False ,1 ,0 ,None ])) print (all ([False ,1 ,0 ,None ]))
1.2 组合类型 1.2.1 列表 列表(list):数据有位置顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 a = [1 , 2 , 3 , 4 , 5 ] a[0 ] ls = ['python' , 1989 , True , {"version" :3.7 }] for i in range (6 ): print (i) len (ls)ls[0 ] a = [1 , 2 ] b = [3 , 4 ] a + b c = a * 10 ls.append(...) ls.insert(1 , 8 ) ls.extend([...]) ls.pop(1 ) ls.remove(...) languages = ['Python' , 'C' , 'R' , 'Java' ] idx = languages.index("R" ) print (idx) languages[1 ] = "C++" languages_2 = languages.copy() languages_3 = languages[:] ls = [...] ls.sort() ls.sort(reverse = True ) ls_2 = sorted (ls) ls = [...] ls.reverse() for i in ls: print (i)
1.2.2 元组 元组(tuple):元素是只读的,不可修改(除了不支持增删改以外,其它的操作和列表完全相同)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 a = (1 , 2 , 3 , 4 , 5 ) a[0 ] def f (x ): return x**2 , x**3 print (f(3 )) a, b = f(3 ) print (a) print (b) numbers = [1 , 2 , 3 ] name = ["小明" , "小红" , "小强" ] list (zip (numbers, name))for number, name in zip (numbers, name): print (number, name)
1.2.3 字典 字典(dict):K-V、无序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 students = {111 :"小明" , 222 :"小红" , 333 :"小强" } students[111 ] len (students) students[新键] = 新值 del students[待删除元素的键]value = students.pop(待删除元素的键) k, v = students.popitem() students[键] = 新值 students.get(key, default) list (students.keys())list (students.values())for k, v in students.items(): print (k, v)
注意:字典的键必须唯一,且是不可变类型。
不可变类型:数字、字符串、元组。
可变类型:列表、字典、集合。
1.2.4 集合 集合(set):去重、无序(元素必须是不可变类型:数字、字符串、元组)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 s = {1 , 2 , 3 , 1 } s s1 & s2 s1 | s2 s1 ^ s2 s1 - s2 s.add(...) s.remove(...) len (...)
2 变量 2.1 定义 变量的定义:变量名、赋值。
2.2 命名 大写字母、小写字母、数字、下划线、汉字及其组合。
错误命名:
命名技巧:
变量名、函数名:用 _ 连接多个单词。
类名:驼峰命名。
常量:所有字母大写。
2.3 赋值 1 2 3 4 5 6 7 8 9 x = 1 + 2 x = x + 1 x += 1 x, y = 1 , 2
3 控制流程 3.1 顺序 3.2 循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 res = 0 for i in [1 , 2 , 3 , 4 , 5 ]: res += i res i = 1 res = 0 while i <= 5 : res += i i += 1 res for i in ...: if i == 2 : break else : while ...: else :
3.3 分支 1 2 3 4 5 6 7 age = 18 if age > 22 : elif age > 30 : else :
判断是否为空:
1 2 3 4 5 6 7 8 if x is None if not xif not x is None
注意:在 Python 语言中,None、""、0、[]、{} 都相当于 False。
4 IO 4.1 读取输入 1 2 3 4 5 6 7 8 9 10 x = input ("..." ) y = input ("..." ) x + y type (x) x = eval (input ("..." )) y = eval (input ("..." )) x + y
4.2 打印输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 print ("..." )print (123 )x = 123 print (x)print (123 , end = 456 )print (789 ) x = 123 y = 456 print ("x = " , x, " y = " , 456 ) x = 1 y = 2 print ("x = {0}, y = {1}" .format (x, y)) PI = 3.1415926 print ("{0:.2f}" .format (PI)) x = 0.81872 print ({0 :.1 %}.format (x)) print ({0 :.2 e}.format (x))
格式化输出总结:
5 函数 5.1 定义 函数名使用小写字母、下划线组成。
1 2 3 4 5 6 7 def 函数名 (参数 ): return 返回值 函数名(参数)
注意:多个函数的定义之间一般空两行。
5.2 参数 函数的参数:形参、实参。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 def function (x, y, z ): print (x, y, z) function(1 , 2 , 3 ) function(y=1 , z=2 , x=3 ) function(1 , z=2 , y=3 ) def register (name, age, sex="male" ): print (name, age, sex) register("..." , 18 ) def name (first_name, last_name, middle_name=None ): if middle_name: return first_name + middle_name + last_name else : return first_name + last_name print ("大" , "仔" )print ("大" , "仔" , "杰" )def f (x, y, z, *args ): print (x, y, z) print (args) f(1 , 2 , 3 , 4 , 5 , 6 ) f(1 , 2 , 3 , [4 , 5 , 6 ]) f(1 , 2 , 3 , *[4 , 5 , 6 ]) def f (x, y, z, **kwargs ): print (x, y, z) print (kwargs) f(1 , 2 , 3 , a=4 , b=5 , c=6 ) f(1 , 2 , 3 , **{"a" :4 , "b" :5 , "c" :6 })
5.3 变量 函数的变量:局部变量、全局变量。
1 2 3 4 5 6 7 8 def multipy (x, y ): global z z = x * y return z multipy(2 , 9 ) print (z)
5.4 返回值 当函数有多个返回值,使用逗号隔开;函数可以没有返回值。
5.5 匿名函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 lambda 变量: 函数体ls = [(93 , 88 ), (79 , 100 ), (86 , 71 )] ls.sort() ls.sort(key = lambda x: x[1 ]) ls.sort(key = lambda x: x[0 ]+x[1 ]) n = max (ls, key = lambda x: x[1 ])
6 面向对象 6.1 定义 三要素:类名(驼峰命名法)、属性、方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Cat (): def __init__ (self, name ): self .name = name def jump (self ): my_cat = Cat("..." ) print (my_cat.name)my_cat.jump()
注意:类的前后都要空两行,清晰美观。
6.2 实例 6.3 继承 语法:class 子类名(父类名)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Car (): def __init__ (self, brand, model, year ): self .brand = brand self .mileage = 0 def get_main_information (): class ElectricCar (Car ): def __init__ (self, brand, model, year, battery_size ): super ().__init__(brand, model, year) self .battery_size = battery_size self .electric_quantity = battery_size
6.4 方法 6.4.1 类实例方法 类实例方法的第一个参数 self 表示实例本身,通过实例对象调用。
以 _ 开头的方法,为大家约定俗成的 private 方法,但实际并不影响程序的行为。
6.4.2 类方法 类方法 @classmethod 只能访问类变量,并且对类属性进行的处理是有记忆的,在多个实例间共享。
参数 cls 指向类本身,允许我们在方法中操作类的属性或调用其他类方法。
类方法可以通过类名或实例对象调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Man : id = 0 def __init__ (self, name ): self .name = name self .id = self .id_number() @classmethod def id_number (cls ): cls.id += 1 return cls.id a = Man('A' ) print (a.id ) b = Man('B' ) print (b.id )
使用类方法可以提供多个构造函数,提高了实例化对象的灵活性。
1 2 3 4 5 6 7 8 9 10 11 class Test : def __init__ (self, x, y ) self .x = x self .y = y @classmethod def from_string (cls, str ): x, y = map (int , s.split(',' )) return cls(x, y) obj = Test.from_string('5,10' )
参考资料:
6.4.3 静态方法 静态方法既不需要传递类对象 cls 也不需要传递实例对象 self 作为第一个参数。
静态方法可以通过类名直接调用,无需创建类的实例,属于类的命名空间中的独立函数。
一般用于工具类中提供的方法。
1 2 3 4 5 6 7 8 9 10 11 class Calculator : @staticmethod def add (x, y ): return x + y @staticmethod def multiply (x, y ): return x * y sum_result = Calculator.add(3 , 5 ) product_result = Calculator.multiply(3 , 5 )
参考资料:
6.4.4 魔术方法 魔法方法是方法名前后各有两个下划线的方法,如 __init__,可以使用 类名() 调用方法。
1 2 3 4 5 6 7 8 9 10 class MyDict (dict ): def __add__ (self, other ): self .update(other) return MyDict(self ) a = MyDict({'de' : 'Germany' }) b = MyDict({'sk' : 'Slovakia' }) print (a + b)
参考资料:
7 文件读写 7.1 打开文件 7.1.1 通用格式 1 2 3 4 5 6 7 8 9 with open ("文件路径" , "打开模式" , encoding = "操作文件的字符编码" ) as f: "对文件进行读写" with open ("E:\ipython\测试文件.txt" , "r" , encoding = "gbk" ) as f: text = f.read() print (text)
注意:当程序与要打开的文件在同一文件夹下时,可以直接写文件名,省略路径。
7.1.2 打开模式
7.1.3 字符编码
万国码:utf-8
中文编码:gbk(Windows 系统默认)
注意:
建议不要缺省 encoding 字段。
当使用 utf-8 读取中文时,会出现乱码。
7.2 读取文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 f.read() f.readline() while True : text = f.readline() if not text: break else : print (text, end="" ) f.readlines() for text in f.readlines(): print (text)
注意:
文本中的空行实际是一个 "\n",文本的末尾实际是一个 ""。
原文每行的末尾已经有了一个 "\n",因此需要取消掉 print() 的自动换行。
文件较大时,read() 和 readlines() 占用内存过大,不建议使用,readline() 又不太方便,可以直接迭代 f 对象:for text in f: ...。
7.3 写入文件 1 2 3 4 5 6 7 8 9 10 11 with open ("...txt" , "w" , encoding="utf-8" ) as f: f.write("..." ) ls = ["..." , "..." , "..." ] with open (...) as f: f.writelines(ls)
7.4 既读又写
"r+":指针在文件的开头,需要将指针移动到末尾(f.seek(...))再开始写。
"w+":若文件已存在,会清空原内容。
"a+":指针在文件的末尾,添加新内容,不会清空原内容。
7.5 数据的读取与存储 7.5.1 csv 1 2 3 4 5 6 7 8 9 10 11 12 13 with open ("xxx.csv" , "r" , encoding="gbk" ) as f: ls = [] for line in f: ls.append(line.strip("\n" ).split("," )) ls = [...] with open ("xxx.csv" , "w" , encoding="gbk" ) as f: for row in ls: f.write("," .join(row) + "\n" )
注意:可以使用 pandas 库实现对 .csv 文件的读取和写入。
7.5.2 json 1 2 3 4 5 6 7 8 9 10 11 12 with open ("scores.json" , "r" , encoding="utf-8" ) as f: scores = json.load(f) for k,v in scores.items(): print (k,v) socres = {...} with open ("scores.json" , "w" , encoding="utf-8" ) as f: json.dump(scores, f, indent=4 , ensure_ascii=False )
8 异常处理 8.1 常见错误 8.2 异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 try : except NameError: except IndexError: except KeyError: else : finally : try : except Exception as e: print (e)
9 模块 9.1 分类
Python 内置模块(time、random、collection、itertools)
第三方库(numpy、pandas、matplotlib、scikit-learn、Tensorflow)
自定义文件(单独文件、包)
9.2 导入 9.2.1 导入整个模块 1 2 3 4 5 6 7 import timestart = time.time() time.sleep() end = time.time() print ("程序运行用时:{:.2f}秒" .format (end-start))
9.2.2 从模块中导入指定的类或函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 from itertools import productls = list (product("AB" , "123" )) print (ls)from function.fun1 import f1f1() from function import fun1, fun2fun1.f1() fun2.f2()
「包」:由多个 .py 文件组成,并且一定需要有一个 __init__.py 文件,该文件可以为空。
注意:这里的模块实际上指的就是 .py 文件。
9.2.3 导入模块中所有的类和函数(不推荐) 1 2 3 4 from random import *print (random())
9.3 查找路径 优先级从高到低:
内存中已经加载的模块。
内置模块:Python 启动时,会默认加载一些 modules 存放在 sys.modules 中。
sys.path 路径中包含的模块。
sys.path 的第一个路径是当前执行文件所在的文件夹。
若需将不在该文件夹内的模块导入,则需要将模块的路径添加到 sys.path 中。
特殊语法 1 解析语法 1.1 列表推导 列表推导:使用解析语法创建列表。
1.1.1 基本结构 基本结构:[expression for value in iterable if condition]
三要素:
1.1.2 执行过程
从可迭代对象中拿出一个元素。
通过 if 条件对元素进行筛选(可省略):
若为 True,则把元素传递给表达式。
若为 False,则继续进行下一次迭代。
将传递给表达式的元素代入表达式进行处理。
将表达式处理的结果加入列表。
1 2 3 4 5 list = []for value in iterable: if condition: list .append(expression)
1.1.3 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ls = [[0 ]*10 for i in range (5 )] ls = [i**2 for i in range (1 ,21 ) if i%2 == 1 ] x = [1 , 2 , 3 ] y = [1 , 2 , 3 ] ls = [i*j for i,j in zip (x, y)] colors = [...] sizes = [...] ls = ["{} {}" .format (color, size) for color in colors for size in sizes] for color in colors: for size in sizes:
1.2 字典推导 1 dic = {i: i**2 for i in range (10 )}
1.3 集合推导 1 set = {i**2 for i in range (10 )}
1.4 生成器表达式 1 s = (i**2 for i in range (10 ))
注意:不存在元组类型的推导,因为元组是不可变的类型。
2 条件表达式 1 2 expr1 if condition else expr2
3 生成器 3.1 基本概念
惰性计算。
无需一次存储海量数据。
一边执行一边计算,只计算每次需要的值。
实际上一直在执行 next() 操作,直到无值可取。
3.2 生成器表达式 1 s = (i**2 for i in range (10000000 ))
3.3 生成器函数 原理:在每次调用 next() 的时候,遇到 yield 语句则返回,再次执行时会从上次返回的 yield 语句处继续执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def fib (max ): n, a, b = 0 , 1 , 1 while n < max : yield a a, b = b, a + b n = n + 1 fib(10 ) for i in fib(10 ): print (i)
4 迭代器 4.1 可迭代对象 可迭代对象(iterable):可用于 for 循环的对象,包括:
可以使用 isinstance() 判断一个对象是否是 Iterable 类型的对象。
1 2 ls = [...] isinstance (ls, Iterable)
4.2 迭代器 生成器不但可以用于 for 循环,还可以被 next() 函数调用。
1 2 3 4 5 6 7 8 s = (i**2 for i in range (5 )) print (next (s))print (next (s))
可以被 next() 函数不断调用并返回下一个值,直到没有数据可取的对象就称为迭代器(Iterator)。
生成器是迭代器;列表、元组、字符串、字典、集合不是迭代器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 iter ([1 , 2 , 3 ])x = [...] y = [...] zip (x, y)nums = [1 , 2 , 3 ] enumerate (nums)with open ("xxx.txt" , "r" , encoding="utf-8" ) as f:
注意:range() 不是迭代器,而是一种序列,它不包含任何内存中的内容,而是通过计算来回答问题。
5 装饰器 5.1 函数对象 函数是 Python 中的第一类对象(class function):
可以把函数赋值给变量。
对该变量进行调用,可以实现原函数的功能。
1 2 3 4 5 6 def square (x ): return x**2 pow_2 = square print (pow_2(5 ))
5.2 高阶函数
1 2 3 4 5 6 7 8 9 def square (x ): return x**2 def pow_2 (fun ): return fun f = pow_2(square) f(8 )
5.3 嵌套函数 嵌套函数:在函数内部定义一个函数。
1 2 3 4 5 6 7 8 9 10 11 def outer (): def inner (): inner() outer()
5.4 闭包 「闭包」:延伸了作用域的函数。如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包。
闭包是由函数及其相关的引用环境组合而成的实体(闭包 = 函数 + 引用环境)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def outer (): x = 1 z = 10 def inner (): y = x + 100 return y, z return inner f = outer() print (f)
一旦在内层函数重新定义了相同名字的变量,则变量成为局部变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 def outer (): x = 1 def inner (): x = x + 100 return x return inner f = outer() f()
使用 nonlocal 允许内嵌的函数来修改闭包变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 def outer (): x = 1 def inner (): nonlocal x x = x + 100 return x return inner f = outer() f()
5.5 装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import timedef timer (func ): def inner (): start = time.time() func() end = time.time() return inner def f1 (): time.sleep(1 ) f1 = timer(f1) @timer def f1 (): time.sleep(1 ) f1()
当被修饰函数有参数时,使用 *arg 和 **kwargs 接收参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def outer (func ): def inner (*arg, **kwargs ): func(*arg, **kwargs) return inner @timer def f1 (n ): time.sleep(n) f1(2 )
当被修饰函数有返回值时,可以先收集结果再进行返回。
1 2 3 4 5 6 7 8 9 def outer (func ): def inner (*arg, **kwargs ): res = func(*arg, **kwargs) return res return inner
装饰器本身也可以带有参数,以实现对不同函数进行不同的修饰。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 def timer (method ): def outer (func ): def inner (*arg, **kwargs ): if method == "origin" : elif method == "double" : return inner return outer @timer(method="origin" ) def f1 (): time.sleep(1 ) @timer(method="double" ) def f2 (): time.sleep(1 ) f1() f2()
注意:被修饰函数一经装饰(即加上注解),就已经被调用了。
6 魔法方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 import timeclass A : def __new__ (cls, *args, **kwargs ): print ("__new__" ) return super ().__new__(cls, *args, **kwargs) def __init__ (self ): print ("__init__" ) def __del__ (self ): print ("__del__" ) def main1 (): a = A() b = a c = a del a del b time.sleep(5 ) class Person : def __init__ (self, name, age ): self .name = name self .age = age def __repr__ (self ): return f"Person(name={self.name} , age={self.age} )" def __str__ (self ): return f"{self.name} is {self.age} years old" def __call__ (self ): print ("__call__" ) def __len__ (self ): print ("__len__" ) return 1 def main2 (): person = Person("Alice" , 25 ) print (person) person() ''' 在 Python 中,使用 __call__() 方法可以实现将类的实例对象作为函数调用的效果,类似于调用一个函数。 当我们调用一个类的实例对象时,Python 会自动调用这个实例对象的 __call__() 方法。 ''' len (person) if __name__ == '__main__' : main1() print ("*" * 20 ) main2()
参考资料:【python】魔术方法大全——基础篇_python中的魔法方法-CSDN博客 。
7 *args & **kwargs 基本概念:
位置参数:函数传入的参数与实际函数的参数在位置和定义的含义需要保持一致(按形参声明的先后顺序一一赋值);
关键字参数:调用函数(key=value)以键值对形式(实参的顺序无所谓)。
注意:关键字参数必须在位置参数的后面。
*args:参数名前加 * 是可变参数,以元组的形式进行存储;
**kwargs:接受任意的关键字参数,会将其参数整体组装成一个字典进行存储。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 def func1 (a, b ): print ('a: ' , a) print ('b: ' , b) def func2 (*args ): print (type (args)) def func3 (**kwargs ): print (type (kwargs)) def func4 (arg, *args, **kwargs ): print ('arg:' , arg) print ('args:' , args) print ('kwargs:' , kwargs) if __name__ == '__main__' : func1(1 , b=1 ) func2(1 , 2 ) my_tuple = (1 , 2 ) func2(*my_tuple) func2(my_tuple) func3(a=1 , b=2 ) my_dict = {'a' : 1 , 'b' : 2 } func3(**my_dict) ''' 注意: 在调用 func2(my_tuple) 时,my_tuple 前可以不加 *,是因为此时 my_tuple 整体被当做了一个元素,传入了可变参数的元组中。 而调用 func3(**my_dict) 时,my_dict 前必须加 **,是因为如果不加 **,此时的 my_dict 整体将被视为一个普通参数。 而 **kwargs 只能接收键值对参数,因此无法直接接收一个字典元素,会报错。 ''' func4(1 , 2 , a=3 ) my_tuple2 = (1 , 2 ) my_dict2 = {'a' : 1 , 'b' : 2 } func4(my_tuple2, my_dict2) ''' 注意: 这里 my_tuple2 整体被当做了 arg,而 my_dict2 整体被当做了 *args 中的一个可变参数。 '''
参考资料:Python关于 *args 和 **kwargs 参数的详解(全)-CSDN博客 。
底层实现 1 列表 1.1 底层实现 列表存储的实际上是其元素的地址,即是一个「引用数组」。
引用数组:
列表内的元素可以分散地存储在内存中。
地址的存储在内存中是连续的。
1.2 浅拷贝 1 2 3 4 5 6 7 8 9 list_1 = [1 , [22 , 33 , 44 ], (5 , 6 , 7 ), {"name" : "sarah" }] list_2 = list_1 list_3 = list_1.copy() list_3[1 ].append(55 )
初始列表:
将两个列表中的第一个元素分别修改为 10 和 20:
将列表二的第二个元素(地址列表)进行修改,列表一的第二个元素也会发生变化:
将列表二的第三个元素(地址元组)进行修改,列表一的第三个元素却不会发生变化:
原因:元组是不可变的类型,当对其进行修改(例如增加元素)时,会产生一个新的元组。
将列表二的第四个元素(字典散列表)进行修改,列表一的第四个元素也会发生变化。
总结:
可变类型:如列表、字典,其内容可以发生变化,而地址不变。
不可变类型:如数字、字符串、元组,一旦其内容发生变化,则地址也会发生变化(会创建一个新的)。
1.3 深拷贝 1 2 3 4 import copylist_2 = copy.deepcopy(list_1)
2 字典 2.1 底层实现 通过「稀疏数组」来实现值的存储与访问。
稀疏数组:数组的许多元素为空,即稀疏的数组。
2.2 创建过程 3 字符串 3.1 底层实现 通过「紧凑数组」实现字符串的存储,数据(字符)在内存中是连续存放的。
4 不可变类型 不可变类型在其生命周期中保持内容不变,如果改变了(如 += 操作)就不是它自己了(创建了一个新的对象),如:数字、字符串、元组。
标准库 1 time 1.1 获取当前时间 1 2 3 4 5 6 7 8 time.localtime() time.gmtime() time.ctime()
1.2 时间戳与计时器 1 2 3 4 5 6 7 8 9 time.time() time.perf_counter() time.process_time()
1.3 格式化输出 1 2 lctime = time.localtime() time.strftime("%Y-%m-%d %A %H:%M:%S" , lctime)
1.4 休眠
2 random 2.1 随机种子
伪随机数:相同的种子会产生相同的随机数。
如果不设置随机种子,以系统当前时间为默认值。
1 2 3 4 5 6 from random import *seed(10 ) print (random) seed(10 ) print (random)
2.2 随机整数 1 2 3 4 5 6 7 8 nums = [randint(1 , 10 ) for i in range (10 )] nums = [randrange(10 ) for i in range (10 )] nums = [randrange(0 , 10 , 2 ) for i in range (10 )]
2.3 随机浮点数 1 2 3 4 5 nums = [random() for i in range (10 )] nums = [uniform(2.1 , 3.5 ) for i in range (10 )]
2.4 序列随机元素 1 2 3 4 5 6 7 8 9 10 11 12 13 seq = ['a' , 'b' , 'c' ] choice(seq) choices(seq, k=5 ) choices(seq, [4 , 4 , 2 ], k) shuffle(seq) sample(seq, k=3 )
2.5 概率分布
3 collections 3.1 具名元组 具名元组(namedtuple):构建一个新的元组子类。
定义方法:
typename:元组的名字。
field_names:域名,即元组中元素的名字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 p = (1 , 2 ) Point = collections.namedtuple("Point" , ["x" , "y" ]) p = Point(1 , y=2 ) print (p.x)print (p.y)print (p[0 ])print (p[1 ])x, y = p
3.2 计数器 计数器(Counter):是字典的一个子类。
1 2 3 4 5 6 7 8 9 10 11 12 13 from collections import Counters = "..." cnt_str = Counter(s) ls = [...] cnt_list = Counter(ls) cnt_list.most_common(1 ) list (cnt_list.elements())
3.3 双向队列 双向队列(deque):可以方便地在队列两边高效、快速地增加和删除元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 from collections import dequed = deque('cde' ) d.append(...) d.appendleft(...) d.pop() d.popleft()
4.1 排列组合迭代器 4.1.1 笛卡尔积 1 2 3 4 5 6 7 from itertoolsfor i in itertools.product('ABC' , '01' ): print (i) for i in itertools.product('ABC' , repeat=3 ): print (i)
4.1.2 排列 1 2 3 4 for i in itertools.permutations('ABCD' , 3 ): print (i) for i in itertools.permutations(range (3 ))
注意:排列的元素是有顺序(先后)的。
4.1.3 组合 1 2 3 4 5 6 7 8 for i in itertools.combination('ABCD' , 2 ): print (i) for i in itertools.combination(range (4 ), 3 )for i in itertools.combination_with_replacement('ABC' , 2 ): print (i)
4.2 拉链 4.2.1 短拉链 1 2 3 4 5 6 7 8 9 10 11 12 for i in zip ("ABC" , "012" , "xyz" ): print (i) for i in zip ("ABC" , "012345" ): print (i)
4.2.2 长拉链 1 2 3 4 5 6 7 for i in itertools.zip_longest("ABC" , "012345" ): print (i) for i in itertools.zip_longest("ABC" , "012345" , fillvalue = "?" ): print (i)
4.3 无穷迭代器 4.3.1 计数
4.3.2 循环 1 2 3 itertools.cycle("ABC" )
4.3.3 重复 1 2 3 4 for i in itertools.repeat(10 , 3 ): print (i)
4.4 其它 4.4.1 锁链 1 2 3 4 for i in itertools.chain('ABC' , [1 , 2 , 3 ]): print (i)
4.4.2 枚举 1 2 3 4 for i in enumerate ("Python" , start=1 ): print (i)
4.4.3 分组 1 2 3 4 5 6 7 for key, group in itertools.groupby('AAABBBBCCCDDDAAABB' ): print (key, list (group))
Numpy 1 特点
底层使用 C 语言实现。
Numpy 数组内的数据类型必须统一(Python 列表支持任意类型),且数据连续存储在内存中(Python 列表的数据分散在内存中),有利于底层的高效处理。
Python 有线程锁,无法实现真正的多线程并行,而 C 语言可以。
当遇到需要使用 for 循环实现一些向量化、矩阵化操作的时候,要优先考虑使用 Numpy,如:两个向量的点乘、矩阵相乘。
2 创建数组 2.1 从列表创建 1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npx = np.array([1 , 2 , 3 , 4 , 5 ]) x = np.array([1 , 2 , 3 , 4 , 5 ], dtype="float32" ) x = np.array([[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]])
2.2 直接创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import numpy as npnp.zeros(5 , dtype=int ) np.ones((2 , 4 ), dtype=float ) np.full((3 , 5 ), 8 ) np.eye(3 ) np.arange(1 , 15 , 2 ) np.linspace(0 , 1 , 4 ) np.logspace(0 , 9 , 10 ) np.random.random((3 , 3 )) np.random.normal(0 , 1 , (3 , 3 )) np.random.randint(0 , 10 , (3 , 3 )) x = np.array(...) np.random.permutation(x) np.random.shuffle(x) x = np.array(...) np.random.choice(x, size=(4 , 3 )) np.random.choice(x, size=(4 , 3 ), p=x/np.sum (x))
3 数组操作 3.1 属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as npx = np.array(...) x.shape x.ndim x.size s.dtype
3.2 索引 1 2 3 4 5 6 7 8 9 10 import numpy as npx1 = array(...) x1[0 ] = ... x2 = array x2[0 , 0 ] = ... x2[0 ][0 ] = ...
注意:Numpy 数组的数据类型是固定的,当向一个整型数组插入一个浮点值时,浮点值会向下进行取整。
3.3 切片 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import numpy as npx1 = np.arange(10 ) x1[:3 ] x1[3 :] x1[::-1 ] x2 = np.random.randint(20 , size=(3 , 4 )) x2[:2 , :3 ] x2[:2 , 0 :3 :2 ] x2[::-1 , ::-1 ] x2[0 , :] x2[0 ] x2[:, 0 ]
注意:切片获取的是「视图」,而非副本,若视图元素发生变化,则原数组也会进行相应的修改。
修改切片的安全方式:x3 = x2[:2, :2].copy()。
3.4 变形 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import numpy as npx1 = np.random.randint(0 , 10 , (12 ,)) x2 = x1.reshape(3 , 4 ) x3 = x1.reshape(1 , x1.shape[0 ]) x4 = x1[np.newaxis, :] x5 = x1.reshape(x1.shape[0 ], 1 ) x6 = x1[:, np.newaxis] x7 = np.random.randint(0 , 10 , (3 , 4 )) x8 = x7.flatten() x9 = x7.ravel() x10 = x7.reshape(-1 )
3.5 拼接 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import numpy as npx1 = np.array([[1 , 2 , 3 ], [4 , 5 , 6 ]]) x2 = np.array([[7 , 8 , 9 ], [0 , 1 , 2 ]]) x3 = np.hstack([x1, x2]) x4 = np.c_[x1, x2] x5 = np.vstack([x1, x2]) x6 = np.r_[x1, x2]
3.6 分裂 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import numpy as npx1 = np.arrange(10 ) x1, x2, x3 = np.split(x1, [2 , 7 ]) x4 = np.arange(1 , 26 ).reshape(5 , 5 ) left, middle, right = np.hsplit(x4, [2 , 4 ]) upper, middle, lower = np.vsplit(x4, [2 , 4 ])
4 运算 4.1 向量运算 「向量运算」:每一次操作都是对矩阵中所有的元素进行操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import numpy as npx1 = [...] x1+5 x1-5 x1*5 x1/5 -x1 x1**2 x1//2 x1%2 abs (x1)np.sin(x1) np.cos(x1) np.tan(x1) np.arcsin(x) np.arccos(x) np.arctan(x) np.exp(x) np.log(x) np.log2(x) np.log10(x) x1 = [...] x2 = [...] x1+x2 x1-x2 x1*x2 x1/x2
4.2 矩阵运算 1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npx = np.arange(9 ).reshape(3 , 3 ) y = x.T x = np.array([1 , 0 ], [1 , 1 ]) y = np.array([0 , 1 ], [1 , 1 ]) x.dot(y)
注意:x.dot(y) 是矩阵乘法,而 x*y 只是将两个矩阵对应位置上的元素直接相乘。
4.3 广播运算 如果两个数组的形状在维度上不匹配,那么数组的形式会沿着维度为 1 的维度进行扩展以匹配另一个数组的形状。
原理如下:
4.4 比较运算和掩码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import numpy as npx1 = np.random.randint(10 , size(10 , 10 )) x1>5 np.sum (x1>5 ) np.all (x1 > 0 ) np.any (x1 == 6 ) np.all (x1 < 8 , axis=1 ) np.all (x1 < 8 , axis=0 ) (x1 > 5 ) & (x1 < 9 ) x2 = [...] x2[x2 > 5 ]
4.5 索引补充 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import numpy as npx1 = [...] ind = [2 , 6 , 9 ] x1[ind] x2 = [...] row = np.array([0 , 1 , 2 ]) col = np.array([1 , 3 , 0 ]) x[row, col] row[:, np.newaxis] x[row[:, np.newaxis], col]
5 其它函数 5.1 排序 1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npx = [...] np.sort(x) s.sort() i = np.argsort(x)
5.2 极值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as npx = [...] np.max (x) np.min (x) max_index = np.argmax(x) min_index = np.argmin(x)
5.3 求和 1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npx = [...] x.sum () np.sum (x) np.sum (x, axis=1 ) np.sum (x, axis=0 )
5.4 求积 1 2 3 4 5 6 7 import numpy as npx = [...] x.prod() np.prod(x)
5.5 统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import numpy as npx = [...] np.median(x) x.mean() np.mean(x) x.var() np.var(x) s.std() np.std(x)
Pandas 1 对象创建 1.1 Series Series 对象是带标签数据的一维数组。
通用结构:pd.Series(data, index=index, dtype=dtype)。
data:数据,可以是列表、字典或 Numpy 数组。
index:索引,可选(默认为:0、1、2、…)。
dtype:数据类型,可选。
1.1.1 通过列表创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import pandas as pddata = pd.Series([1.5 , 3 , 4.5 , 6 ]) data = pd.Series([1.5 , 3 , 4.5 , 6 ], index=["a" , "b" , "c" , "d" ]) data = pd.Series([1.5 , 3 , 4.5 , 6 ], index=["a" , "b" , "c" , "d" ], dtype="float" ) data = pd.Series([1 , 2 , "3" , 4 ], index=["a" , "b" , "c" , "d" ]) data["a" ] data = pd.Series([1 , 2 , "3" , 4 ], index=["a" , "b" , "c" , "d" ], dtype=float )
1.1.2 通过Numpy一维数组创建 1 2 3 4 5 import pandas as pdimport numpy as npx = np.arange(5 ) pd.Series(x)
1.1.3 通过字典创建 1 2 3 4 5 6 7 8 9 import pandas as pddict = {...}pd.Series(dict ) pd.Series(dict , index=[...])
1.1.4 通过标量创建 1 2 3 4 5 6 7 import pandas as pdpd.Series(5 , index=[1 , 2 , 3 ])
1.2 DataFrame DataFrame 对象是带标签数据的多维数组。
通用结构:pd.DataFrame(data, index=index, columns)。
data:数据,可以是列表、字典或 Numpy 数组。
index:索引,可选。
columns:列标签,可选(默认为 0)。
1.2.1 通过Series对象创建 1 2 3 4 5 6 import pandas as pdpopulation_dict = {...} population = pd.Series(population_dict, columns=["population" ]) pd.DataFrame(population)
1.2.2 通过Series对象字典创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import pandas as pdGDP = pd.Series(GDP_dict) pd.DataFrame({"population" : population, "GDP" : GDP}) """ population GDP beijing ... ... shanghai ... ... shenzhen ... ... """ pd.DataFrame({"population" : population, "GDP" : GDP, "country" : "China" }) """ population GDP country beijing ... ... China shanghai ... ... China shenzhen ... ... China """
1.2.3 通过字典列表对象创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import pandas as pddata1 = [{"a" : i, "b" : 2 *i} for i in range (3 )] pd.DataFrame(data1) """ a b 0 0 0 1 1 2 2 2 4 """ data2 = [{"a" : 1 , "b" : 1 }, {"b" : 3 , "c" : 4 }] pd.DataFrame(data2) """ a b c 0 0 1 NaN 1 NaN 3 4.0 """
1.2.4 通过Numpy二维数组创建 1 2 3 import pandas as pdpd.DataFrame(np.random.randint(10 , size=(3 , 2 )), column=["foo" , "bar" ], index=["a" , "b" , "c" ])
2 DataFrame的性质 2.1 属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import pandas as pddata = pd.DataFrame(...) data.values data.index data.columns data.shape data.size data.types
2.2 索引
数据表如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import pandas as pddata = pd.DataFrame(...) data["pop" ] data[["pop" , "GDP" ]] data.GDP data.loc["BeiJing" ] data.loc[["BeiJing" , "HangZhou" ]] data.iloc[0 ] data.iloc[[1 , 3 ]] data.loc["BeiJing" , "GDP" ] data.iloc[0 , 1 ] data.values[0 ][1 ] data.GDP["BeiJing" ]
2.3 切片
数据表如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import pandas as pdimport numpy as npdates = pd.date_range(start='2019-01-01' , periods=6 ) df = pd.DataFrame(np.random.randn(6 , 4 ), index=dates, columns["A" , "B" , "C" , "D" ]) df["2019-01-01" : "2019-01-03" ] df.loc["2019-01-01" : "2019-01-03" ] df.iloc[0 : 3 ] df.loc[:, "A" : "C" ] df.iloc[:, 0 : 3 ] df.loc["2019-01-01" : "2019-01-02" , "C" : "D" ] df.iloc[1 : 3 , 2 :] df.loc["2019-01-04" : "2019-01-06" , ["A" , "C" ]] df.iloc[3 :, [0 , 2 ]] df.loc[["2019-01-04" , "2019-01-06" ], "C" : "D" ] df.iloc[[1 , 5 ], 0 : 3 ] df.loc[["2019-01-04" , "2019-01-06" ], ["A" , "C" ]] df.iloc[[1 , 5 ], [0 , 2 ]]
2.4 布尔索引 布尔索引:即掩码操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import pandas as pdimport numpy as npdates = pd.date_range(start='2019-01-01' , periods=6 ) df = pd.DataFrame(np.random.randn(6 , 4 ), index=dates, columns["A" , "B" , "C" , "D" ]) df > 0 df[df > 0 ] df.A > 0 df[df.A > 0 ] df2 = df.copy() df2['E' ] = ['one' , 'one' , 'two' , 'tree' , 'four' , 'tree' ] ind = df2["E" ].isin(["two" , "four" ]) df2[ind]
2.5 赋值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import pandas as pdimport numpy as npdates = pd.date_range(start='2019-01-01' , periods=6 ) df = pd.DataFrame(np.random.randn(6 , 4 ), index=dates, columns["A" , "B" , "C" , "D" ]) s1 = pd.Series([1 , 2 , 3 , 4 , 5 , 6 ], index=pd.date_range('20190101' , periods=6 )) df["E" ] = s1 df.loc["2019-01-01" , "A" ] = 0 df.iloc[0 , 1 ] = np.nan df["D" ] = np.array([5 ]*len (df)) df["D" ] = 5 df.index = [i for i in range (len (df))] df.columns = [i for i in range (df.shape[1 ])]
3 数值运算及统计分析 3.1 查看数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import pandas as pdimport numpy as npdates = pd.date_range(start='2019-01-01' , periods=6 ) df = pd.DataFrame(np.random.randn(6 , 4 ), index=dates, columns["A" , "B" , "C" , "D" ]) df.head() df.head(2 ) df.tail() df.tail(3 ) df.info()
3.2 Numpy通用函数 3.2.1 向量化运算 1 2 3 4 5 6 7 8 9 10 import pandas as pdimport numpy as npx = pd.DataFrame(np.arange(4 ).reshape(1 , 4 )) x+5 np.exp(x) y = pd.DataFrame(np.arange(4 , 8 ).reshape(1 , 4 )) x*y
3.2.2 矩阵化运算 1 2 3 4 5 6 7 8 9 10 11 12 13 import pandas as pdimport numpy as npx = ... y = ... x.dot(y) %timeit x.dot(y) %timeit np.dot(x, y)
注意:
Numpy 更侧重于计算,计算速度快。
Pandas 是基于 Numpy 的,计算速度比 Numpy 慢,更侧重于数据的分析和处理。
3.2.3 广播运算
数据表如下:
1 2 3 4 5 6 7 8 9 10 11 import pandas as pdimport numpy as npx/x.iloc[0 ] x.div(x.iloc[0 ], axis=1 ) x.div(x.A, axis=0 ) x.div(x.iloc[0 ], axis=1 )
3.3 特有方法 3.3.1 索引对齐 1 2 3 4 5 6 7 8 9 10 11 import pandas as pdimport numpy as npA = pd.DataFrame(...) B = pd.DataFrame(...) A+B A.add(B, fill_value=0 )
3.3.2 统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 import pandas as pdimport numpy as npfrom collections import Countery = np.random.randint(3 , size=20 ) np.unique(y) Counter(y) y1 = pd.DataFrame(y, columns=["A" ]) np.unique(y1) y1["A" ].value_counts() y.sort_values(by="列名" ) y.sort_values(by="列名" , ascending=False ) y.sort_index() y.sort_index(axis=1 ) y.sort_index(axis=1 , ascending=False ) y.count() y.sum () y.sum (axis=1 ) y.max () y.min () y.idmax() y.idmin() y.max (axis=1 ) y.min (axis=1 ) y.mean() y.var() y.std() y.median() y.mode() y.quantile(0.75 ) y.describe() y.corr() y.corrwith(df["A" ]) def my_describe (x ): return pd.Series([x.count(), x.mean(), x.max (), x.idxmin(), x.std()], index=["count" , "mean" , "max" , "min" , "idxmin" , "std" ]) y.apply(my_describe)
4 缺失值处理 4.1 发现缺失值 1 2 3 4 5 6 7 8 import pandas as pdimport numpy as npdata.isnull() data.notnull()
注意:
NaN 即 np.nan,是一种特殊的浮点数。
有 None、字符串等类型时,数据类型将全部变为 object 类型,它比 int 和 float 更加消耗资源。
4.2 删除缺失值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import pandas as pdimport numpy as npdata.dropna() data.dropna(axis="columns" ) data.dropna(axis="columns" , how="all" ) data.dropna(axis="columns" , how="any" )
4.3 填充缺失值 1 2 3 4 5 6 7 8 9 10 11 import pandas as pdimport numpy as npdata.fillna(value=5 ) data.fillna(value=data.mean()) data.fillna(value=data.stack().mean())
5 合并数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import pandas as pdpd.concat([df_1, df_2]) pd.concat([df_3, df_4], axis=1 ) pd.concat([df_5, df_6], ignore_index=True ) pd.merge(df_7, df_8)
对齐合并:
6 分组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import pandas as pddf.groupby("列名" ) df.groupby("列名" ).sum () df.groupby("列名" ).mean() df.groupby("列名" )["列名2" ].sum () for data, group in df.groupby("列名" ): df.groupby("列名" )["列名2" ].describe() df.groupby("列名" ).aggregate(["min" , "median" , "max" ]) def filter_func (x ): return x["列名" ].std() > 3 df.groupby("列名" ).filter (filter_func) df.groupby("列名" ).transforms(lambda x: x - x.mean()) def func (x ): x["列名1" ] /= x["列名2" ].sum () return x df.groupby("列名" ).apply(func) L = [0 , 1 , 0 , 1 , 2 , 0 ] df.groupby(L).sum ()
7 数据透视表 1 2 3 4 5 6 7 8 9 10 11 import pandas as pddata.pivot_table("要分析的列名" , index="列名1" , columns="列名2" ) data.pivot_table("要分析的列名" , index="列名1" , columns="列名2" , aggfunc="mean" , margins=True ) data.pivot_table(index="列名1" , columns="列名2" , aggfunc={"列名3" : "sum" , "列名4" : "mean" })
8 其它 Matplotlib 1 环境配置 1.1 自动显示 在 Jupiter 中,可以通过在代码开头加上 %matplotlib inline,使我们绘制的图像自动进行显示。
在 pycharm 中需要手动添加 plt.show()。
1.2 设置样式 1 2 3 4 5 6 7 8 9 10 11 import matplotlib.pyplot as pltplt.style.available[:5 ] with plt.style.context("seaborn-white" ): plt.plot(x, y) plt.style.use("seaborn-whitegrid" )
1.3 保存文件 1 2 3 import matplotlib.pyplot as pltplt.savefig("my_figure.png" )
2 库函数 2.1 折线图 2.1.1 线条样式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0 , 2 *np.pi, 100 ) plt.plot(x, np.sin(x)) plt.plot(x, np.cos(x)) plt.show() plt.plot(x, np.sin(x), color="..." ) plt.plot(x, np.sin(x), linestyle="..." ) plt.plot(x, np.sin(x), linewidth="数字" ) plt.plot(x, np.sin(x), marker="..." ) plt.plot(x, np.sin(x), marker="..." , markersize=10 ) plt.plot(x, np.sin(x), color_linestyle) plt.plot(x, np.sin(x), color_marker_linestyle)
2.1.2 坐标轴 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0 , 2 *np.pi, 100 ) plt.plot(x, np.sin(x)) plt.xlim(-1 , 7 ) plt.ylim(-1.5 , 1.5 ) plt.axis([-2 , 8 , -2 , 2 ]) plt.axis("tight" ) plt.axis("equal" ) ?plt.axis plt.xscale("log" ) plt.xticks(np.arange(0 , 12 , step=1 ), fontsize=15 ) plt.yticks(...) plt.tick_params(axis="both" , labelsize=15 )
2.1.3 图形标签 1 2 3 4 5 6 7 8 9 10 11 12 import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0 , 2 *np.pi, 100 ) plt.plot(x, np.sin(x)) plt.title("..." , fontsize=20 ) plt.xlabel("x" , fontsize=15 ) plt.ylabel("sin(x)" , fontsize=15 )
2.1.4 图例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0 , 2 *np.pi, 100 ) plt.plot(x, np.sin(x)) plt.plot(x, np.sin(x), "b--" , label="sin" ) plt.plot(x, np.cos(x), "r--" , label="cos" ) plt.legend() plt.legend(loc="upper center" , frameon=True , fontsize=15 )
2.1.5 文字 1 2 3 4 5 6 import matplotlib.pyplot as pltplt.text(3.5 , 0.5 , "y=sin(x)" , fontsize=15 )
2.1.6 箭头 2.2 散点图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import matplotlib.pyplot as pltx = np.linspace(0 , 2 *np.pi, 100 ) plt.scatter(x, np.sin(x), marker="o" , s=30 , c="r" ) y = x**2 plt.scatter(x, y, c=y, cmap="Blues" ) plt.colorbar() plt.scatter(x, y, c=y, s="数组" , cmap="Blues" ) plt.scatter(x, y, c=y, s="数组" , cmap="Blues" , alpha=0.3 )
2.3 柱形图 2.3.1 普通柱形图 1 2 3 4 5 6 7 8 9 10 11 12 13 import matplotlib.pyplot as pltimport numpy as npx = np.arange(1 , 6 ) plt.bar(x, x*2 , align="center" , width=0.5 , alpha=0.5 , color="yellow" , edgecolor="red" ) plt.tick_params(axis="both" , labelsize=15 ) plt.xticks(x, ("G1" , "G2" , ...))
2.3.2 累加柱形图 1 2 3 4 5 6 7 8 9 10 import matplotlib.pyplot as pltimport numpy as npx = np.arange(5 ) y1 = np.random.randint(20 , 30 , size=5 ) y2 = np.random.randint(20 , 30 , size=5 ) plt.bar(x, y1, width=0.5 , label="man" ) plt.bar(x, y2, width=0.5 , bottom=y1, label="woman" ) plt.legend()
2.3.3 并列柱形图 1 2 3 4 5 6 7 8 9 10 import matplotlib.pyplot as pltimport numpy as npx = np.arange(5 ) y1 = np.random.randint(20 , 30 , size=5 ) y2 = np.random.randint(20 , 30 , size=5 ) plt.bar(x, y1, width=0.5 , label="man" ) plt.bar(x+0.5 , y2, width=0.5 , label="woman" ) plt.legend()
2.3.4 横向柱形图 1 2 3 4 5 6 7 8 9 import matplotlib.pyplot as pltimport numpy as npx = ['G1' , 'G2' , ..., 'G5' ] y = 2 *np.arange(1 , 6 ) plt.barh(x, y, align="center" , height=0.5 , alpha=0.8 , color="blue" , edgecolor="red" ) plt.tick_params(axis="both" , labelsize=15 )
2.4 多子图 2.4.1 普通多子图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import matplotlib.pyplot as pltplt.subplot(221 ) plt.subplot(222 ) plt.subplot(223 ) plt.subplot(224 )
2.4.2 不规则多子图 1 2 3 4 5 6 7 8 9 import matplotlib.pyplot as pltgrid = plt.GridSpec(2 , 3 , wspace=0.4 , hspace=0.3 ) plt.subplot(grid[0 , 0 ]) plt.subplot(grid[0 , 1 :]) plt.subplot(grid[1 , :])
2.5 直方图 2.5.1 普通直方图 1 2 3 import matplotlib.pyplot as pltplt.hist(x, bins=50 , facecolor='g' , alpha=0.75 )
2.5.2 概率 1 2 3 4 5 6 7 import matplotlib.pyplot as pltplt.hist(x, 50 , destiny=True , color="r" ) plt.hist(x, 50 , destiny=True , cumulative=True , color="r" )
2.6 误差图 2.7 面向对象 2.8 三维图像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from mpl_toolkits import mplot3dax = plt.axes(projection="3d" ) zline = np.linespace(0 , 15 , 1000 ) xline = np.sin(zline) yline = np.cos(zline) ax.plot3D(xline, yline, zline) zdata = 15 *np.random.random(100 ) xdata = np.sin(zdata) ydata = np.sin(zdata) ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap="spring" ) def f (x, y ): return np.sin(np.sqrt(x**2 + y**2 )) x = np.linspace(-6 , 6 , 30 ) y = np.linspace(-6 , 6 , 30 ) X, Y = np.meshgrid(x, y) Z = f(X, Y) ax = plt.axes(projection="3d" ) ax.plot_surface(X, Y, Z, camp="viridis" )
3 Seaborn Seaborn 是一个基于 matplotlib 且数据结构与 pandas 统一的统计图制作库。
4 Pandas绘图函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import pandas as pddf = pd.DataFrame(...) df.plot() df.plot.bar() df.plot.bar(stacked=True ) df.plot.barh(stacked=True ) df.plot.hist(bins=20 ) df['列名' ].plot.hist(cumulative=True ) df['列名' ].plot(kind="kde" ) df.plot(kind="scatter" , x="median_income" , y="median_house_value" , alpha=0.8 ) df.plot(subplot=True , figsize=(6 , 16 )) df.plot(subplot=True , layout=(2 , 2 ), figsize=(6 , 16 ), sharex=False )
Sklearn 1 数据预处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import seaborn as snsimport pandas as pdfrom sklearn.preprocessing import LabelEncoderfrom sklearn.preprocessing import StandardScalerfrom sklearn.model_selection import train_test_splitiris = sns.load_dataset("iris" ) type (iris)iris.head() iris.info() iris.describe() iris.species.value_counts() sns.pairplot(data=iris, hue="species" ) iris_simple = iris.drop(["sepal_length" , "sepal_width" ], axis=1 ) encoder = LabelEncoder() iris_simple["species" ] = encoder.fit_transform(iris_simple["species" ]) trans = StandardScaler() _iris_simple = trans.fit_transform(iris_simple[["petal_length" , "petal_width" ]]) _iris_simple = pd.DataFrame(_iris_simple, columns = ["petal_length" , "petal_width" ]) train_set, test_set = train_test_split(iris_simple, test_size=0.2 ) iris_x_train = train_set[["petal_length" , "petal_width" ]] iris_y_train = train_set["species" ].copy() iris_x_test = test_set[["petal_length" , "petal_width" ]] iris_y_test = test_set["species" ].copy()
2 基本分类算法 2.1 k近邻算法 2.1.1 基本思想 在训练数据集中,找到与带预测点最近的 k 个邻居,把这 k 个邻居中最常见的类别预测为该待预测点的类别。
2.1.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from sklearn.neighbors import KNeighborsClassifierclf = KNeighborsClassifier() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)encoder.inverse_transform(res) accuracy = clf.score(iris_x_test, iris_y_test) out = iris_x_test.copy() out["y" ] = iris_y_test out["pre" ] = res out.to_csv("iris_predict.csv" ) draw(clf)
2.2 朴素贝叶斯算法 2.2.1 基本思想 当 X=(x1, x2, …)(特征)发生的时候,求哪一个 yk(类别)发生的概率最大。
2.2.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from sklearn.naive_bayes import GaussianNBclf = GaussianNB() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
2.3 决策树算法 2.3.1 基本思想 CART 算法:每次通过一个特征,将数据尽可能的分为纯净的两类,并一直递归地分下去。
2.3.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from sklearn.tree import DecisionTreeClassifierclf = DecisionTreeClassifier() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
2.4 逻辑回归算法 2.4.1 基本思想
训练:通过一种映射方式,将特征 X=(x1, x2) 映射为概率 P(y=ck),并求使得所有概率之积最大化的映射方式里的参数。
预测:计算 P(y=ck),并取概率最大的那个类别作为预测对象的分类。
2.4.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from sklearn.linear_model import LogisticRegressionclf = LogisticRegression(solver='saga' , max_iter=1000 ) clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
2.5 支持向量机算法 2.5.1 基本思想 以二分类为例,假设数据集可以完全分开。
用一个超平面将两类数据完全分开,且最近点到平面的距离最大。
2.5.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from sklearn.svm import SVMclf = SVM() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
3 集成方法 3.1 随机森林 3.1.1 基本思想 对于训练集 m,有放回地随机抽取 m 个数据构成一组,共抽取 n 组采样集。
n 组采样集训练得到 n 个弱分类器,弱分类器一般用决策树或神经网络。
将 n 个弱分类器进行组合得到强分类器。
3.1.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from sklearn.ensemble import RandomForestClassifierclf = RandomForestClassifier() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
3.2 Adaboost 3.2.1 基本思想 对于训练集 m,用初始数据权重训练得到第一个弱分类器,根据误差率计算弱分类器的系数,并更新数据的权重。
使用新的权重来训练数据,得到第二个弱分类器,以此类推。
根据各自的系数,将所有弱分类器加权求和获得强分类器。
3.2.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from sklearn.ensemble import AdaBoostClassifierfrom sklearn.naive_bayes import GaussianNBclf = AdaBoostClassifier() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
3.3 梯度提升树 3.3.1 基本思想 对于训练集 m,获得第一个弱分类器,计算残差,然后不断地拟合残差。
将所有的弱分类器相加得到强分类器。
3.3.2 sklearn实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from sklearn.ensemble import GradientBoostingClassifierclf = GradientBoostingClassifier() clf.fit(iris_x_train, iris_y_train) res = clf.predict(iris_x_test) print (res)print (iris_y_test.values)accuracy = clf.score(iris_x_test, iris_y_test) draw(clf)
4 改进方法 4.1 XGBoost
梯度提升树的损失函数只对误差部分做负梯度(一阶泰勒)展开。
XGBoost 的损失函数对误差部分做二阶泰勒展开,更加准确,更加收敛。
4.2 lightgbm lightgbm 是由微软发布的,快速的、分布式的、高性能的基于决策树算法的梯度提升框架。
4.3 stacking 堆叠(模型融合)是指先建立几个简单的模型进行训练,第二级学习器会基于前级模型的预测结果进行再训练。
4.4 神经网络 刷题常用 1 常用数据结构 1.1 列表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import copyls = [0 , 1 , 2 , 3 , 4 , 5 ] max (ls)min (ls)ls_1 = ls[5 ::-1 ] print (ls_1) ls_2 = ls[4 :2 :-1 ] print (ls_2) grid = [[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]] grid_1 = grid.copy() grid_1[0 ][1 ] = 0 print (grid) print (grid_1) grid_2 = copy.deepcopy(grid) grid_2[1 ][1 ] = 0 print (grid) print (grid_2) del grid_2[0 ]
1.2 集合 特点:无序、去重。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 set_1 = {1 , 2 , 3 } set_2 = set () if 4 in set_1: print ("4 is in set_1" ) set_3 = set ('abracadabra' ) print (set_3) set_4 = {x for x in 'abracadabra' if x not in 'abc' } print (set_4) set_1.add(4 ) set_1.add({5 , 6 }) print (set_1) set_1.remove(7 ) set_1.discard(7 ) set_1.pop() set_1.clear()
1.3 字典 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 dict_1 = {} dict_2 = dict () """ 注意: 1.字典值可以是任何的python对象,既可以是标准的对象,也可以是用户自定义的,但键不行。 2.键必须是唯一的,但值则不必。 3.键必须不可变,所以可以用数字、字符串或元组充当,而用列表就不行。 """ dict_3 = {'Name' : 'Runoob' , 'Age' : 7 , 'Class' : 'First' } print (dict_3['Name' ]) dict_3['Name' ] = 'W3' print (dict_3['Name' ]) del dict_3['Name' ]print (dict_3) dict_3.clear() print (dict_3) dict_4 = {'Name' : 'Runoob' , 'Age' : "7" , 'Class' : 'First' } for k in dict_4: print (k) for k in dict_4.keys(): print (k) for v in dict_4.values(): print (v) print (dict_4.items()) for k, v in dict_4.items(): print (k + ": " + v) for k, v in zip (dict_4.keys(), dict_4.values()): print (k + ": " + v) if 'Score' not in dict_4: dict_4['Score' ] = 10 else : dict_4['Score' ] += 10 print (dict_4)
1.4 栈 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 stack = [] stack.append(1 ) stack.append(2 ) stack.append(3 ) print (stack) print (stack.pop()) print (stack[-1 ]) if len (stack) != 0 : print ("stack is not empty" )
1.5 队列 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import collectionsimport queuequeue_list = [1 , 2 , 3 ] queue_list.append(4 ) print (queue_list) print (queue_list.pop(0 )) queue_1 = queue.Queue() queue_1.put(1 ) queue_1.put(2 ) queue_1.put(3 ) print (queue_1.get()) queue_2 = queue.LifoQueue() queue_3 = queue.PriorityQueue() queue_4 = collections.deque() queue_4.append(1 ) queue_4.append(2 ) print (queue_4.pop()) queue_4.appendleft(3 ) queue_4.appendleft(4 ) print (queue_4.popleft())
1.6 堆 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import heapqheap_1 = [] heapq.heappush(heap_1, 1 ) heapq.heappush(heap_1, 5 ) heapq.heappush(heap_1, 2 ) print (heap_1) heap_2 = [2 , 3 , 1 , 4 ] heapq.heapify(heap_2) print (heap_2) print (heapq.heappop(heap_2)) print (heapq.heappop(heap_2)) print (heapq.heappop(heap_2)) heap_3 = [7 , 6 , 3 , 2 , 9 , 0 , 1 , 5 , 4 ] print (heapq.nlargest(3 , heap_3)) print (heapq.nsmallest(3 , heap_3))
1.7 排序 1.7.1 列表排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ls = [[1 , 9 ], [2 , 8 ], [3 , 7 ]] ls.sort(key=lambda x: x[1 ]) print (ls) ls_1 = sorted (ls, key=lambda x: x[1 ], reverse=True ) print (ls_1) print (ls) """ 注意: 1.sort() 是直接原地修改列表。 2.sorted() 会创建一个新的列表(浅拷贝)-> 内部嵌套的数组实际复制的是其地址,指向的还是同一块内存。 """ ls_1[0 ][1 ] = 6 print (ls_1) print (ls)
1.7.2 字典排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import functoolsdef my_cmp (o1, o2 ): if o1[1 ] != o2[1 ]: return o1[1 ] - o2[1 ] else : return o2[0 ] - o1[0 ] dict_1 = {1 : 100 , 2 : 98 , 3 : 99 } dict_2 = sorted (dict_1.items(), key=lambda x: x[0 ]) print (dict_2) dict_3 = sorted (dict_1.items(), key=lambda x: x[1 ], reverse=True ) print (dict_3) dict_1[4 ] = 99 dict_ls = list (dict_1.items()) dict_4 = sorted (dict_ls, key=functools.cmp_to_key(my_cmp)) print (dict_4) print (dict_4[0 ][0 ])
1.7.3 堆排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import heapqclass Student : def __init__ (self, name: str , age: int , score: int ): self .name = name self .age = age self .score = score def __lt__ (self, other ): if self .age != other.age: return self .age < other.age else : return other.score < self .score heap_stu = [] heapq.heappush(heap_stu, Student("张三" , 3 , 100 )) heapq.heappush(heap_stu, Student("李四" , 4 , 80 )) heapq.heappush(heap_stu, Student("王五" , 4 , 90 )) heap_sort = sorted (heap_stu) print (heap_sort[0 ].name) print (heap_sort[1 ].name) print (heap_sort[2 ].name)
2 常用函数 2.1 print() 1 2 3 4 5 6 7 8 print ("abc" )print ("abc" , end="\n" )print ("abc" , end="" ) print ("abc" , end=" " )
3 字符串 3.1 字符串的分割 1 2 3 4 5 6 7 8 my_str = 'https://www.baidu.com/pdf/abcdefg.pdf' print (str .split())print (str .split('/' )) print (str .split('/' )[0 ]) print (str .split('/' )[-1 ].split('.' )[0 ])
3.2 str转int 1 2 3 4 5 6 7 8 import stringa = "123" int (a)string.atoi(a)
3.3 判断相等 在 Python 中,== 被用来判断两个对象的值是否相等,内容相同的字符串实际上就是同一个对象(与 Java 不同,Java 中的 == 被用来判断是否是同一个对象)。
1 2 3 4 5 str_1 = "abc" str_2 = "abc" print (str_1 == str_2) print (str_1 is str_2)
4 类型提示 Python 是动态类型语言,运行时不需要指定变量类型。Python 3.5 引入了一个类型系统,允许开发者指定变量类型(类型提示)。
使用方式:
声明函数的参数类型:在参数名称的后面加上 :,并带上类型的名称;
声明函数的返回值类型:在函数声明结束之前,也就是 : 之前加入一个 ->,并在箭头的后面带上类型的名称。
常用数据类型:
基本类型:int、long、float;
集合类型:List、Tuple、Dict、Set;
布尔类型:bool、str;
迭代器类型:Iterable、Iterator;
生成器类型:Generator。
示例:
1 2 3 4 5 6 7 8 9 10 11 from typing import Dict , Tuple , Sequence ConnectionOptions = Dict [str , str ] Address = Tuple [str , int ] Server = Tuple [Address, ConnectionOptions] def broadcast_message (message: str , servers: Sequence [Server] ) -> None : def broadcast_message (message: str , servers: Sequence [Tuple [Tuple [str , int ], Dict [str , str ]]] ) -> None :