python数据分析怎么提升逻辑思维_数据分析学习大法:0基础学Python系列专题

现如今,大数据的发展越来越好,也越来越多的企业中大数据分析已经朝着更好的方向发展。也正是因为这个原因,数据分析行业的人才需求也变得火爆起来,尤其是数据分析、数据挖掘、数据科学家等高端人才,越来越稀缺。

当然,对于数据分析这个工作,的确是需要学会一些编程语言的,比如MATLAB,Python,Java等语言。但是对于初学者来说,Python是一个不错的语言,Python语言简单易懂还具有强大的编程能力,同时对于大数据分析有很明显的帮助。

0基础无障碍学习Python系列专题(一)

今天的主要关键内容是我们Python中最基础的两个部分,变量名命名规则和字符串方法。在处理数据的过程中,我们需要创建一些变量名进行赋值,那变量名命名时有什么规则呢?

变量名命名规则变量名由数字、字母、下划线组成。但不能以数字开头

命名时应当避开关键字。

#查看python关键字

import keyword

kw = keyword.kwlist

print(kw)

#运行结果

['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

在Python中方法相当于函数功能,Python为我们提供了许多方法便于我们处理数据,接下来我们接触几个简单的字符串方法。体验一下他们神奇。

字符串方法center 通过在两边添加填充字符(默认为空格)让字符串居中

b = "我想居中"

print(b.center(80))

print(b.center(80,"-"))​ 我想居中

--------------------------------------我想居中--------------------------------------find 在字符串中查找子串。如果找到,就返回子串的第一个字符的索引,否则返回-1

index 在字符串中查找子串。如果找到,就返回子串的第一个字符的索引,否则引发ValueErorr异常

h = 'my name is Lexi'

print(h.find('m'))

print(h.index('n'))

#两个函数都可限制搜索范围

print(h.find('n',0,2)) #同时制定起点和终点

print(h.index('n',2)) #只制定了起点join 用于合并序列的元素

#合并一个字符串列表

sep = ["1","3","4","5"]

seq = '+'

seq.join(sep)

#用 join 地址拼接场景

dirs = '','usr','bin','env'

print('C:'+'\\'.join(dirs))lower 返回字符串的小写版本

'Hello World'.lower()

'classical my girl'.title() #首词大写

#在string模块中有个capwords可以实现首词大写

import string

string.capwords("that's your book")replace 将指定的子串都替换为另一个字符串,并返回替换后结果

'this is your book'.replace('is','eez')split 返回一个列表,按照分割符进行划分

'1+2+3+4+5'.split('+')strip 删除指定字符

rstrip 从右边删除指定字符

lstrip 从左边删除指定字符

#去除输入的空格

k = input("请输入一个数字")

print(k.strip())

#去除指定的字符(只能去除开头或者结尾的字符,中间的还是会被保留)

clear = '###$%%^^%$#^!#!$!'

print(clear.strip("#"))

0基础无障碍学习Python系列专题(二)

主要关键内容列表新建索引

切片

序列的加法和乘法

成员资格

列表方法元组

字典字典常用方法

写在前面Python内置了多种序列,列表和元组是其中最常用的两种;

列表和元组的主要区别在于,列表可以修改,而元组不可以;

常规操作包括索引、切片、插入、删减等。

列表新建新建一个列表;

列表由中括号为容器,每个元素之间用逗号间隔。

#新建一个列表:

alist = [1,"nihao","hello","你好"]

print(alist)

索引列表中所有元素都有编号—从0开始递增;

列表中第一个元素编号为0,最后一个元素编号为-1。

alist = [1,"nihao","hello","你好"]

alist[0] #取出alist中的第一个元素1

alist[-1] #取出alist中的最后一个元素"你好"

alist[2] #取出alist中的第三个元素"hello"

切片用索引我们可以访问单个元素,而切片可以让我们访问多个元素

使用两个索引值,并用冒号分隔

blist = [1,2,3,4,5,6,7,8,9,10] #新建一个列表blist

blist[0:3] #取出blist中前3个元素[1,2,3]

blist[7:10] #取出blist中后3个元素[8,9,10]

#添加步长参数

blist[0:4:2] #按步长为2,取出blist中前4个元素.[1,3]

#小应用:提取域名

wangzhi = input("请输入网址") #输入http://www.xiaokeai.com

yuming = wangzhi[11:-4] #截取域名

print(yuming) #返回 xiaokeai

序列的加法和乘法

[1,3,4]+[4,6,7] #运行结果为[1, 3, 4, 4, 6, 7]

[1,3,4]*4 #运行结果为[1, 3, 4, 1, 3, 4, 1, 3, 4, 1, 3, 4]

成员资格用in判断元素是否在列表中,存在返回True,不存在返回False

#判断输入的内容是否存在

users = ["王二麻子","李大嘴","赵四","大墩子"] #简历列表users

user_name = input("请输入你的名字:") #输入

user_name in users

列表方法append 将一个对象附加到列表结尾

insert 将一个对象插入到列表中的指定位置

extend 将多个值添加进列表末尾

lst = [3,7,32,8,13,34] #创建新列表lst

lst.append(3) #添加新元素3

print(lst) #打印结果[3, 7, 32, 8, 13, 34, 3]

tst = [3,7,32,8,13,34] #创建新列表tst

tst.insert(3,"hello") #插入新元素,使得新元素的索引为3

print(tst) #打印结果[3, 7, 32, 'hello', 8, 13, 34]

ist = [3,7,32,8,13,34] #创建新列表ist

a = [1,3,4] #创建新列表a

ist.extend(a)

print(ist) #打印结果[3, 7, 32, 8, 13, 34, 1, 3, 4]

#extend添加与加法(ist+a)的主要区别是,extend改变了ist的内容,而加法没有改变istcopy 复制列表

count 计算出指定的元素在列表中出现了多少次

index 查找指定值第一次出现的索引

a = [1,2,3] #创建新列表a

b = a.copy() #将a复制给b

print(b) #输出结果[1,2,3]

b[1] = 4 #改变b中的元素

print(a,b) #a不会被改变,输出[1, 2, 3] [1, 4, 3]

k = ["two","to","san","two",["two","two"]] #新建列表k

k.count("two") #统计k中"two"的个数,返回结果2

k.index("to") #返回to第一次出现的索引值,结果为1pop 从列表中删除末尾元素,并返回这一元素

remove 用于删除第一个为指定值的元素

clear 清空列表内容

del 删除列表中元素(del语句不属于方法)

x = [1,2,3] #创建新列表x

x.pop() #删除了最后一个元素,并返回3

print(x) #输出结果[1,2]

y = [4,65,86,4,56,5] #创建新列表y

y.remove(4) #删除列表中第一个4

print(y) #输出结果[65, 86, 4, 56, 5]

j = [5,432,5425.6,51] #创建新列表j

j.clear() #清除列表

print(j) #打印结果[]

l = ["to","be","am","is","are"] #创建新列表l

del l[2] #删除l中索引为2的元素

print(l) #输出结果['to', 'be', 'is', 'are']sort 对列表进行排序,默认为从小到大排序,或者按字母顺序排序。调整参数可以调整排序方式。

h = [32,54,6,8,2,543,6576,243]

h.sort()

print(h) #输出结果[2, 6, 8, 32, 54, 243, 543, 6576],按数字大小

h.sort(reverse=True)

h.reverse()

print(h) #调整sort中reverse参数或者直接使用reverse方法可以倒序排序,输出结果为[6576, 543, 243, 54, 32, 8, 6, 2]

y = ["p","y","t","h","o","n"]

y.sort()

print(y) #输出结果['h', 'n', 'o', 'p', 't', 'y'],按字母先后顺序

name = ["dhjak ","jkl","dsafd","dasjkdal"]

name.sort(key=len) #调整sort的key参数,可以实现按文本长度排序

print(name) #输出结果['jkl', 'dsafd', 'dhjak ', 'dasjkdal']

元组以小括号形式体现的数据集,不同元素之间用逗号隔开;

元组许多功能与列表相似,唯一区别是不能进行修改元素。语法也很简答,在这就不一一赘述。

字典字典由“{}”、“键”以及“值”组合而成,键和值之间用“:”相连。每个键值对之间由“,”相隔;

字典是一种无序的映射的集合。包含若干个键值对;

其中字典中的键通常采用字符串,但也可以用数字、元组等类型;字典值则可以是任意类型。

思考:有了列表和元组两个容器,我们为什么还需要用字典呢?

接下来给大家举一个例子,用该例子说明我们字典的优势。

#开学了,现在我们这有一份学员名单,以及每个学员的性别,如下:

name = ["zhao","qian","sun","li","zhou","wu","zheng","wang"]

gender = ["F","M","F","F","M","F","M","M"]

#现在我们想知道同学"sun"的性别,于是我们写了以下代码:

print(gender[name.index("sun")])

#上面这行代码当然是可以为我们反馈正确结果的,但是这个代码写起来非常麻烦。如果我们建立了字典,将会大大简化我们的代码。步骤如下:

xueyuan = {"zhao":'F',"qian":'M',"sun":'F',"li":'F',"zhou":'M',"wu":'F',"zheng":'M',"wang":'M'}

print(xueyuan["sun"])

从刚才这个小例子,我们看到了字典的优势,也知道了如何建立字典容器。接下来我们来看字典的基本操作:len(dict)返回dict字典中包含的项(键值对)个数;

dict[a]返回与键a相关联的值;

dict[b] = value 讲b值关联到key2;

del dict[c] 删除c的项;

e in d 检查字典d是否包含键为e的项;

dict1 = {"name":"zhang","age":10} #创建字典

print(len(dict1)) #用函数len()求出字典dict1的键值对个数,返回2

print(dict1["name"]) #通过"[键]"可以查出该键所对应的的值,返回"zhang"

dict1["age"]=12 #更改age所对应的值

print(dict1) #返回结果{'name': 'zhang', 'age': 12}

del dict1["age"] #删除"name"项

print(dict1) #返回结果{'name': 'zhang'}

"name" in dict1 #检查字典dict1中是否包含"name"项,返回True

字典的常用方法pop() 从字典中删除,并返回映射值

popitem() 从字典中删除并返回键值对元组

clear() 删除字典内的全部对象

d1 = {"a":1,"b":2,"c":3} #创建字典d1

d1.pop("a") #删除键为a的键值对,并且返回值1

print(d1) #返回{'b': 2, 'c': 3}

d1.popitem() #随机的删除d1中某一对键值对,并返回键值对元组。因为字典是无序的,不能确定他每次删除的是哪一项键值对。如果本身字典为空,在执行该语句会报错。

d1.clear() #清除字典内全部对象

print(d1) #返回{}copy() 复制字典对象

x = {"name":"张三","age":"9"} #创建一个字典

y = x #直接复制时,x和y引用同一个字典

print(x,y) #返回{'name': '张三', 'age': '9'} {'name': '张三', 'age': '9'}

y["name"]="李四" #将y中键"name"的值改为"李四"

print(x) #x也跟随改变,{'name': '李四', 'age': '9'}

#可以用方法copy()解决这个问题

y = x.copy() #y引用复制字典

y["name"] = "王五" #讲y中键"name"的值改为"王五"

print(y,x) #x也跟随改变,{'name': '王五', 'age': '9'} {'name': '李四', 'age': '9'}get(key[,default]) 返回key键映射的值。如果key不存在,返回空值。可以用default参数指定不存在的键的返回值。如下例

x = {"name":"张三","age":"9"} #创建一个字典

x.get("name") #返回键"name"对应值"'张三'

x.get("gender") #没有"gender"键,所以返回空

x.get("gender","none") #设定default参数,当没有"gender"键,返回"none"setdefault(key[,default]) 用该方法返回映射值或者添加键值对。

upgrade() 为字典添加键值对,若字典已存在同名的键,则映射值被覆盖。

x = {"name":"张三","age":"9"} #创建一个字典

x.setdefault("name") #返回键"name"对应值"'张三'

x.setdefault("gender") #添加新键值对

print(x) #返回{'name': '张三', 'age': '9', 'gender': None},默认给None值

x.setdefault('phone','123') #添加新键值对

print(x) #返回{'name': '张三', 'age': '9', 'gender': None, 'phone': '123'}items() 返回键值对视图

keys() 返回字典中所有键的视图

values() 返回字典中所有值的视图

y = {'name': '张三', 'age': '9', 'gender': None, 'phone': '123'} #创建一个字典

x.items() #返回键值对视图 dict_items([('name', '张三'), ('age', '9'), ('gender', None), ('phone', '123')])

x.keys() #返回所有键的视图 dict_keys(['name', 'age', 'gender', 'phone'])

x.values() #返回所有值的视图 dict_keys(['name', 'age', 'gender', 'phone'])

0基础无障碍学习Python系列专题(三)

主要关键内容:函数编写与传参方式函数是组织好的,可重复使用的的代码段;

函数能提高应用的模块性,和代码的重复利用率。

定义函数与调用函数以 def 关键词开头,后接函数名,函数名后接 ();

()之间可以用于定义参数;

函数内容以冒号起始,并且转行缩进;

return代表着函数结束,选择性地返回一个值给调用函数。

#定义函数基本格式如下:

def 函数名(参数表):

函数语句

return 返回值

#参数和返回值都不是必须有的,例如:

def hello(): #定义函数

print("hello world")

hello() #调用函数,返回hello world

#而下面这个例子是为函数定义了两个参数,并用return语句返回值。

def add(a,b): #定义函数

return(a+b)

add(1,3) #调用函数,返回4

函数参数(重点)定义函数时,参数表中的参数称为形式参数,简称形参;

调用函数时,参数表中的参数称为实际参数,简称实参。

参数具有多态性传入不同类型变量,得到不同结果。

def duo(a,b): #定义函数

return(a+b)

duo(1,4) #调用传入两个int值,返回结果5

duo("oh"," my god") #调用并传入两个字符串,返回结果'oh my god'

duo((3,4),("g","h")) #调用并传入两个元组,执行元组合并,返回(3, 4, 'g', 'h')

duo([7,4],[6,7,8,9]) #调用并传入两个列表,执行列表合并,返回[7, 4, 6, 7, 8, 9]

参数赋值传递函数调用时按参数的先后顺序,将实参传递给形参;

可以以形参赋值的方式,指定将实参传递给形参。

def fu(a,b):

return(a+b) #定义函数

fu("ab","cd") #返回"abcd",按对应位置将实参传递给了形参;

fu(b="cd",a="ab") #依然返回"abcd",通过形参赋值传参。

可变参数(小心使用)当实参是可变对象时,如列表、字典。如在函数中修改形参,因为共享引用。通过实参也获得修改后的对象;

详见以下例子。

def kebian1(k): #定义函数

k[1] = "hello"

x = [9,10]

kebian1(x) #调用函数,传递列表对象的引用

print(x) #返回[9, 'hello'],变量原本的引用被修改

#嗯哼~那么问题来了!!我们应该如何规避这个问题?(看下行的时候请先思考)

#------------------------------------------------------------------

#我们规避的思路就是,复制一份,将克隆的传入形参。原本变量不受影响,如下例:

k = [1,2]

kebian1(k[:]) #调用函数,传递拷贝下来的变量

print(k) #返回[1, 2],变量没被改变

#还可以在函数内对列表进行拷贝,如下例:

def kebian2(k): #定义函数

k = q[:] #拷贝

k[1] = 'hello'

q = [3,4]

kebian2(q) #调用函数,传递列表对象的引用

print(q) #返回[3, 4],变量没被改变

参数默认值在定义函数的时候,我们可以给参数设置一个默认值。这样我们在调用函数未提供实参时,函数将按照默认参数执行;

带默认值的参数,应当放在参数表的末尾;

为避免出错,默认参数必须指向一个不可变参数。

def info(name = "",degree = "未填写"): #定义函数,并将参数degree赋予一个默认值“未填写”

print(name,degree)

info("熊猫酱") #当只输入一个实参时,会返回熊猫酱 未填写

info("熊猫酱","博士") #当输入两个实参时,会返回熊猫酱 博士

传递任意个参数定义函数是,若参数名前带有"*"号,则表示可接受任意个数的参数,并保存在一个元组中;

传参时,"*"号后面的参数必须以关键字传参。

def add(a,*b,c): #定义函数

s = a+c

for i in b: #为了保证语法不出错,当函数带有"*"号的参数时,需要用for循环来循环元组内内容

s += i

return s

add(1,2,4,c=9) #返回结果16,注意*b,后面的参数,传参是必须带上关键字。

0基础无障碍学习Python系列专题(四)

主讲关键内容:Python的面向对象

Python的类在这门语言中,类使用 class 语句来定义。在类中包含了一系列语句,比如赋值语句,def 定义函数等。从面向对象的角度看,类封装了对象的行为和数据。在Python的类中变量就是对象的数据,函数就是对象的行为,函数也成为方法。

Python中的对象在Python的对象模型中,有两种对象:类对象和实例对象。类对象是用 class 语句创建的,而实例对象是在调用类的时候创建的。所以类对象只有一个,而实例对象可以有多个。

类对象执行 class 语句创建一个类对象和一个变量;

类中的赋值语句创建的变量是类的数据属性,在类中的顶层赋值语句创建的变量才属于类属性;

类中定义的 def 语句的函数是类的方法属性;

类的数据和方法和所有实例对象共享。

实例对象实例对象通过调用类对象来创建;

每个实例对象继承类对象的属性,并获得自己的命名空间;

实例对象可以拥有“私有”属性。类的方法函数的第一个参数默认为 self,表示引用方法的对象实例。在方法中地域 self 的属性赋值才会创建术语实例对象的属性

[^]: 摘自《python3基础教程》侵删 。这个是本文作者看了诸多教材后,从中对比出最简单理解的一版。肯定还是很枯燥,但如果是零基础的读者还是要硬着头皮看完再看后面的内容。

定义类

基本格式如下代码:

class Student: #创建了一个名为Student的类,我们约定类的首字母大写。

data = 200 #在此,我们定义了类的属性.

def set_name(self,name): #用def语句定义了类的方法

self.name = name

def show_name(self):

return self.name

print("类Student创建完成")

调用类

type(Student) #首先我们检查一下我们类的类型,返回type

Student.data #调用了类的属性,返回200

Student.set_name() #试图调用类的方法,会直接报错。类的方法并不能直接调用,只能通过实例对象调用。

#正确调用类方法的姿势如下:

banji1 = Student() #创建一个实例对象banji1

banji1.set_name("amy") #传入参数

banji1.show_name() #调用方法,显示实例对象属性值,返回'amy'

banji2 = Student() #创建另一个实例对象banji2

banji2.set_name('tom') #传入参数

banji2.show_name() #调用方法,显示实例对象属性值,返回'tom'。从这可看出,实例对象属性之间没有什么关系。

banji1.data,banji2.data #返回(200, 200),访问了共享属性

对象的属性

在Python中,实例对象继承了类对象的所有属性和方法,可以用dir()函数查看

dir(Student)

dir(banji1)

#这个代码返回信息太长,可以自行运行查看一下。以双下划綫开头结尾的变量名术语内置属性,最后我们可以看到来自Student类对象的data、set_name、show_name三个属性。

共享属性

类对象的数据属性是全局的,改变类对象的属性,实例对象引用时也会被改变。实例对象的数据属性更改不影响其他实例对象或者类对象。

banji3 = Student() #创建Student的实例对象,并用banji3引用该对象

banji4 = Student() #创建Student的实例对象,并用banji4引用该对象

print(Student.data,banji3.data,banji4.data) #返回200 200 200

Student.data = 100 #改变全局变量属性

print(Student.data,banji3.data,banji4.data) #返回100 100 100,实例对象属性跟随改变

banji3.data = 400 #更改实例变量的data属性赋值

print(Student.data,banji3.data,banji4.data) #返回100 400 100,实例对象属性改变,不影响他人

实例对象可以拥有私有属性

“私有”强调属性只属于当前实例对象,对其他实例对象是不可见的。

banji5 = Student() #创建Student的实例对象,并用banji5引用该对象

# banji5.set_name() #试图访问实例对象的属性,结果报错显示并不存在

banji5.set_name("john") #调用类的对象方法为属性赋值

banji5.show_name() #返回"john"

类的私有属性

如果想要类的方法或者属性成为私有的,不能通过实例对象引用,只需要在期名称以两个下划线开头即可。如下例:

class Secret:

def __invisible(self):

print("you can't see")

def visible(self):

print("what you can not see is:")

self.__invisible()

#这样创建,我们就不能从外部访问__invisible,但是可以通过invisible访问

s = Secret()

# s.__invisible() #试图从外部访问,直接报错

s.visible() #访问成功,返回what you can not see is: you can't see

#其实,在类定义中,所有以两下划线开头的名称都被进行了转化,就是加了个下划线和类名

dir(Secret) #用dir查看,我们发现列表中有'_Secret__invisible',知道这个以后,我们可以从外部访问类的私有对象了

s._Secret__invisible() #成功返回you can't see。但这中操作并不正规

魔法函数init

又名构造函数,在调用类创建实例对象时自动被调用,不需要手动调用。

class Boy(object):

def __init__(self):

#方法,用来做变量初始化或赋值操作,在类实例化对象的时候,会被自动调用

self.name = "yyg"

self.height = "180"

self.weight = "170"

def info(self):

print("我叫{},身高{},体重{}".format(self.name,self.height,self.weight))

def show(self):

"""实例方法"""

print("你的嘤嘤怪以上线")

boyfriend = Boy()

# 只需要调用实例方法info(),即可获取数据

boyfriend.info() #返回我叫yyg,身高180,体重170

boyfriend.show() #返回你的嘤嘤怪以上线

0基础无障碍学习Python系列专题(五)

​ ——那些被遗忘而好用的函数

主讲关键内容:

lambda函数

map()函数

递归函数

lambda 函数

最开始接触循环,我们就写了一个函数实现了1加到100。我们是这样写的:

my_sum = 0

for i in range(1,101):

my_sum += i

print(my_sum)

就像上面写的一样,代码非常简短明朗就能实现我们的需求。但是如果我们需求变成1加到1000或者50加到100等等我们就需要用到def函数。

def my_sum(x,y):

res = 0

for i in range(x,y):

res += i

return res

my_sum(50,101) #调用函数,返回3825

my_sum(1,1001) #调用函数,返回500500

lambda函数写起来非常简单,不需要命名函数,可以直接输出结果.经常与一些高级函数结合使用:lambda关键字后面跟参数,可以跟多个参数

参数后跟冒号,冒号后接的相当于return后面的内容

lambda定义的是单行函数,如果需要复杂函数,还是应该选择普通函数

lambda表达式中不能含有命令,而且仅限一条表达式

如果我们用lambda函数我们将两行搞定这件事情,如下:

from functools import reduce #python3.x以上需要导入reduce模块

reduce(lambda x,y:x+y,range(1,101))#正确返回结果5050

map()函数map()是 Python 内置的高阶函数

map函数一般第一个参数是一个函数,可以是内置函数,也可以是自定义函数;第二个参数一个可迭代对象

map将接收的函数,依次作用在可迭代对象的每一个元素中中并返回一个map对象,类似于这种格式

map对象可以转化成list,或者用遍历将他显示出来

list(map(lambda x:x*2,[1,2,3]))

#返回[2, 4, 6].此函数讲[1,2,3]中每个元素都按照lambda公式要求乘以2,并用list将他们转化成了列表格式

#利用map()函数与lambda结合,我们可以解决一个网红python题,找1000以内的水仙花数

#(“水仙花数”是一个三位数其各位数字的立方和等于该数本身)

for i in range(100,1000):

if sum(map(lambda x:int(x)**3,str(i)))==i:

print(i)

#这段简短代码可读性很高我就不一一细说了,你细品~

如果我们能结合自定义公式,那想找几位的水仙花数都非常easy啦,请看我的表演

def shuixianhua(n): #自定义函数shuixianhua

x = 10**(n-1)

y = 10**n

res = []

for i in range(x,y):

if sum(map(lambda z:int(z)**n,str(i))) == i:

res.append(i)

return res

shuixianhua(3) #返回[153, 370, 371, 407]

shuixianhua(4) #返回[1634, 8208, 9474]

递归函数递归函数指函数体体内调用函数本身;

使用递归函数,必须设定一个基线条件,就是满足这一条件时,直接返回一个值

以下是递归的经典案例:

1.阶乘问题:用我们之前所学的内容我们可以这样解决阶乘问题

#思路:先定义res变量为n,在让其一次乘以1到n-1每一个数字

def jiecheng(n):

res = n

for i in range(1,n):

res *= i

return res

jiecheng(3) #返回1*2*3的值,6如果用递归方法实现阶乘问题,我们首先要理清她的基线条件:

1的阶乘为1

大于1的数字n,其阶乘为n依次乘以1到n-1

def jc(n):

if n == 1: #如果是1,返回1

return 1

else:

return n * jc(n-1) #如果不是1,再次调用函数本身

jc(4) #返回1*2*3*4的值,24

2.幂问题

- 说到幂问题,要插播一个内置函数,pow(x,n),返回x的n次幂

- 然后再用普通姿势定义一个函数power,让他实现pow()的功能

#思路将n个x相乘

def power(x,n):

res = x

for i in range(1,n):

res *= x

return res

power(2,3)如果用递归方法实现幂问题,我们首先要理清她的基线条件:

1的0次方为1

def power(x,n):

if n == 0: #如果是0,返回1

return 1

else:

return x * power(x,n-1) #如果不是0,再次调用函数本身

power(2,3) #返回8

3.用递归函数解决一元二次函数求解问题

import math

def func(a,b,c):

delta = b**2-4*a*c

x = -b/(2*a)

if delta == 0:

print("只有一个根{}".format(x))

elif delta > 0:

x1 = x + math.sqrt(delta)/(2*a)

x2 = x - math.sqrt(delta)/(2*a)

print("有两个根,{},{}".format(x1,x2))

else:

print("无实根")

func(1,2,1)

0基础无障碍学习Python系列专题(六)

主讲关键内容:继承如果在子类中定义了__init__()方法,父类的__init__() 不会被自动调用,需要在子类中显示调用

子类中调用父类方法时,以父类类名为前缀,并以self做为第一个参数.区别于在类中调用普通函数是不需要带上self参数

Python总是首先在子类中查找对应方法,如果子类中没有找到,才会找到父类中逐个查找

#### 单继承当我们定义了一个类A,还需要建立一个B,但是A和B两者属性大致相同。那么可以利用继承的方法,让B继承A的属性,而不是重头开始写个B。

class University():

def __init__(self):

self.level = '双一流大学'

print("University:yes")

def getLevel(self):

print('University:self level is:',self.level)

class College(University):

pass

a = University() # 返回University:yes

a.getLevel() # 返回University:self level is: 双一流大学

b = College() # 返回University:yes

b.getLevel() # 返回University:self level is: 双一流大学

#在这个例子中,子类College默认没有__init__属性时,会直接继承父类University的__init__

#如果子类中有定义__init__,子类必须显示地在__init__()函数中再次调用父类的__init__()函数。

继承与抽象继承是基于抽象的过程

以下是大学里建立教职工与学员信息表的代码,如下:

class Teachers(): #建立教职工的类

def __init__(self,name,age,tea_id):

self.name = name

self.age = age

self.tea_id = tea_id

def say_hello(self):

print('My name is {},{} years old'.format(self.name,self.age))

print('I am a teacher,my id is {}'.format(self.tea_id))

class Students(): #建立学生的类

def __init__(self,name,age,stu_id):

self.name = name

self.age = age

self.stu_id = stu_id

def say_hello(self):

print('My name is {},{} years old'.format(self.name,self.age))

print('I am a student,my id is {}'.format(self.stu_id))Students和Teachers类都有共同的属性name和age,并且say_hello方式相同,可以对他们进行抽象,归类为People,建立派生类Sudents和Teachers。代码如下:

class People:

def __init__(self,name,age,id):

self.name = name

self.age = age

self.id = id

def say_hello(self):

print('My name is%s,%syears old'%(self.name,self.age))

print('My id is%s'%self.id)

class Students(People):

pass

class Teachers(People):

pass

p = Students('amy','18','o090909')

q = Teachers('john','22','i090979')

p.say_hello()

#返回结果如下:

# My name is amy,18 years old

# My id is o090909

q.say_hello()

#返回结果如下:

# My name is john,22 years old

# My id is i090979

覆盖现在需要解决的就是要区分出是老师还是学生

思路:

覆盖People中的say_hello方法

Students调用say_hello方法时多输出一句"I am a student",同理Teachers类多输出一句"i am a teacher"

调整后代码如下:

class People:

def __init__(self,name,age,id):

self.name = name

self.age = age

self.id = id

def say_hello(self):

print('My name is%s,%syears old'%(self.name,self.age))

print('My id is%s'%self.id)

class Students(People):

def say_hello(self):

People.say_hello(self) #调用父类方法

print('I am a student')

class Teachers(People):

def say_hello(self):

People.say_hello(self) #调用父类方法

print('I am a teacher')

p = Students('amy','18','o090909')

q = Teachers('john','22','i090979')

p.say_hello()

#返回结果如下:

# My name is amy,18 years old

# My id is o090909

# I am a student

q.say_hello()

#返回结果如下:

# My name is john,22 years old

# My id is i090979

# I am a teacher

多重继承子类可以继承多个父类

class Father1():

father1_data = 'this is father_1'

def father_1(self):

return 'this is father_1 def'

class Father2():

father2_data = 'this is father_2'

def father_2(self):

return 'this is father_2 def'

class Son(Father1,Father2):#子类Son同时继承Father1和Fahter2类

def son_def(self):

return 'this is son def'

s = Son()

print(s.father1_data) # 返回this is father_1

print(s.father2_data) # 返回this is father_2

s.father_1() # 返回'this is father_1 def'

s.father_2() # 返回'this is father_2 def'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值