Python初级教程-廖雪峰Python教程

目录

demo1-输入输出

demo2-布尔变量

demo3-变量

demo4-字符串格式化

demo5-列表

demo6-元组

demo7-条件判断 

demo8-for循环 

demo9-字典与集合

demo10-可变对象与不可变对象

demo11-内置函数

demo12-定义函数与isinstance

demo13-默认参数

demo14-默认参数必须指向不可变对象

demo15-可变参数

demo16-关键字参数与命名关键字参数

demo17-函数参数顺序

demo18-random常见函数

demo19-切片

demo20-可迭代对象Iterable

demo21-列表生成式

demo22-生成器

demo23-迭代器

demo24-map与reduce函数

demo25-filter函数

demo26-sorted函数

demo27-匿名函数lambda

demo28-类和实例

demo29-数据封装

demo30-访问限制

demo31-继承与多态

demo32-字符串

demo33-列表del/remove/reverse 

demo34-删除包含特定值的所有列表元素 

demo35-可变对象(列表、字典)作为函数参数


demo1-输入输出

#demo-1
#输入输出
#print函数参数
#转义字符
#正数 浮点数 字符串

name = input("Please enter your name:")
print("hello,",name)

print("2**10 =",2**10) #注意:print函数的逗号默认为一个空格,这是因为sep参数默认为空格
print("2**10=",2**10,sep="")#因此可以将sep参数设置为""

print(2**5) #正数
print(3.1415926)#浮点数:IEEE754 浮点数的存储不精确
print("hello world") #打印字符串:字符串可以用单引号也可以用双引号,每个pritn后默认换行

print("hello ",end="") #注意:可以将end参数设置为"",这样就不会换行
print("world")

print("i'm ok")#""中含有'
print('i" ok')#''中含有“
print("i\' \"ok\"") #既有单引号与双引号 则使用转义字符\

print('\\\t\\')
print(r'\\\t\\')#r表示原生字符串,不转义,可以对比输出结果
Please enter your name:ddd
hello, ddd
2**10 = 1024
2**10=1024
32
3.1415926
hello world
hello world
i'm ok
i" ok
i' "ok"
\	\
\\\t\\

demo2-布尔变量

#demo-2
#Bool变量
#注意大小写
#布尔值可以用and or not运算
#if语句

True
False

print(3>2)
print(3<2)

print("----and----")
print(True and True)
print(False and True)
print(True and False)
print(False and False)
print("----or----")
print(True or True)
print(False or True)
print(True or False)
print(False or False)
print("----not----")
print(not True)
print(not False)

#布尔值常用if结合使用
#if首先判断条件为True或者Fasle,然后执行相应语句
print("*"*20)#字符串还可以这样,使用*重复打印
age = 22
if age>0:
    print("Positive")
elif age<0:
    print("negative ")
else:
    print("zeros")
print("*"*20)
True
False
----and----
True
False
False
False
----or----
True
True
True
False
----not----
False
True
********************
Positive
********************

demo3-变量

#demo-3
#变量
#变量名由大小写字母、数字和_组成,不能以数字开头
#变量赋值:对变量赋值x = y是把变量x指向真正的对象,该对象是变量y所指向的。随后对变量y的赋值不影响变量x的指向
#除法

"""getVar可以由int变为float,这是因为Python是动态语言,变量本身类型不固定
    例如C或C++,变量声明或初始化时需要首先指定变量类型,且类型不可变
"""
getVar = 5 #驼峰命名法  # =为赋值,相当于在内存中创建了一个getVar的变量与5,并将getVar变量指向5
print(getVar)
getVar = 3.1415
print(getVar)

#两种写法均为将getVar加上5后再重新赋给getVar
getVar = getVar + 5 
getVar += 5
print(getVar)


#把一个变量a赋值给另一个变量b,实际上是把变量b指向变量a所指向的数据
print("!!!重要!!!")
tempA = "tempValue" #此时tempA指向tempValue
tempB = tempA       #此时tempB也指向tempValue
print(tempA,tempB)
tempA = "hello world" #此时tempA指向hello world,但tempB仍然指向tempValue
print(tempA,tempB)

print("\n*****除法*****")
print(10/3) #精确的除法
print(10//3)#地板除 向下取floor,只取整数部分
print(10%3) #mod求模得余数
5
3.1415
13.1415
!!!重要!!!
tempValue tempValue
hello world tempValue

*****除法*****
3.3333333333333335
3
1

demo4-字符串格式化

#demo-4
#字符串格式化
#爬虫中结构化的URL中常用
urlList = ["https://www.renrendai.com/loan-{}.html".format(i)  for i in range(5)]
for eachList in urlList:
    print(eachList)
    
testStr = "my name is {},my age is {}".format("zsl",999)
print(testStr)

#使用索引
testStr = "my name is {1},my age is {0}".format("zsl",999)
print(testStr)
https://www.renrendai.com/loan-0.html
https://www.renrendai.com/loan-1.html
https://www.renrendai.com/loan-2.html
https://www.renrendai.com/loan-3.html
https://www.renrendai.com/loan-4.html
my name is zsl,my age is 999
my name is 999,my age is zsl

demo5-列表

#demo-5
#列表list-有序集合
print("*****创建列表*****")
test = [10,3.1415,"a",["C","C++"],{"key":"value",}] #Python中的列表可以是不同类型
scoresList = [60,80,100]
print(test)
print(test[3][1]) #取列表中的列表
print(scoresList)
print("*****列表长度*****")
print(len(scoresList)) #列表长度
print("*****正向索引*****")
print(scoresList[0])#正向索引/从0开始
print(scoresList[1])
print(scoresList[2])
print("*****反向索引*****")
print(scoresList[-1])#反向索引:-1代表最后一个
print(scoresList[-2])#-2代表倒数第二个
print(scoresList[-3])#PS:若越界则报错
print("*****append追加*****")
print(scoresList)
scoresList.append(120)
print(scoresList)
print("*****insert插入*****")
print(scoresList)
scoresList.insert(0,0)#在索引为0处插入0
print(scoresList)
scoresList.insert(3,999)#在索引为0处插入0
print(scoresList)
print("*****pop删除*****")
print(scoresList)
scoresList.pop()#默认弹出最尾部元素
print(scoresList)
scoresList.pop(3) #弹出索引为0的元素
print(scoresList)
print("*****替换列表元素*****")
print(scoresList)
scoresList[0] = 9999
print(scoresList)

*****创建列表*****
[10, 3.1415, 'a', ['C', 'C++'], {'key': 'value'}]
C++
[60, 80, 100]
*****列表长度*****
3
*****正向索引*****
60
80
100
*****反向索引*****
100
80
60
*****append追加*****
[60, 80, 100]
[60, 80, 100, 120]
*****insert插入*****
[60, 80, 100, 120]
[0, 60, 80, 100, 120]
[0, 60, 80, 999, 100, 120]
*****pop删除*****
[0, 60, 80, 999, 100, 120]
[0, 60, 80, 999, 100]
[0, 60, 80, 100]
*****替换列表元素*****
[0, 60, 80, 100]
[9999, 60, 80, 100]

demo6-元组

#demo-6
#tuple元组
#tuple与list非常相似,但tuple一旦初始化后无法修改
scoresTuple = (60,80,100)
print(scoresTuple)

#初始化后无法修改,也无insert append pop等方法
#scoresTuple[0]=999 #T会报错ypeError: 'tuple' object does not support item assignment

#定义只有一个元素的tuple
oneTuple = (1)
print(oneTuple,type(oneTuple))
oneTuple = (1,) #需要加个, 因为()既可以生成tuple,也可以认为是表达式的小括号,有ambiguous
print(oneTuple,type(oneTuple))

print("****有趣的例子*****")
testTuple = (1,2,[3,4])
print(testTuple)
testTuple[2][0] = 666
testTuple[2][1] = 999
print(testTuple) #实质变的不是tuple,tuple始终指向两个整数一个列表,变的只是tuple中列表元素所指向的值
# testTuple[2] = [666,999] #这样则会报错,因为这是修改tuple所指向的元素,而tuple在初始化后就不能修改所指向的值

(60, 80, 100)
1 <class 'int'>
(1,) <class 'tuple'>
****有趣的例子*****
(1, 2, [3, 4])
(1, 2, [666, 999])

demo7-条件判断 

#demo-7
#条件判断

#if语句从上往下执行,如果有个判断语句为True,则执行相应语句
#往后的elif与else则忽略
#例如下面的if中,num也满足大于0,但不会输出statement2
#所以注意if语句中各个判断条件的顺序或者具体判断内容
num = 10
if num > 5:
    print("statement1")
elif num > 0:
    print("statement2")
else:
    print("else")
    
boolValue = 4>3

if boolValue: #关键是只要判断内容是True则会执行
    print("test")
statement1
test

demo8-for循环 

#demo-8
#for循环

print("*****打印列表的每个值*****")
scoresLists = [0,60,80,100]
for eachScore in scoresLists:
    print(eachScore)
    
print("*****求列表数字总和*****")
scoresLists = [0,60,80,100]
scoresSum = 0
for eachScore in scoresLists:
    scoresSum += eachScore
print(scoresSum)
print("*****求1-100和*****")
mySum = 0
for each in range(1,101): #range(start,end)-左开右闭即[start,end)
    mySum += each
print(mySum)
print("*****for循环常见用法-enumerate:既要每个元素的值也要每个元素对应的索引*****")
for index,each in enumerate(range(1,21,3)): #range(start,end,step) 其中step为步长
    print(index,each)
    
print("*****for循环常见用法-zip:同时遍历两个可迭代对象*****")
for x,y in zip([1,2,3],[4,5,6]): #
    print(x,y)

#break语句可以在循环过程中直接退出循环,而continue语句可以提前结束本轮循环,并直接开始下一轮循环。这两个语句通常都必须配合if语句使用”
print("*****continue:计算1-100的偶数和*****")
mySum = 0
for each in range(1,101):
    if each % 2 != 0:#计算偶数和,则遇到奇数时continue进入下一次循环
        continue
    mySum += each #只有偶数情况时才会执行该语句
print(mySum)
print("*****break*****")
mySum = 0
for each in range(1,101):
    if each % 2 != 0:
        break #第一次碰见奇数时就break结束循环,因此mySum仍为0
    mySum += each 
print(mySum)
*****打印列表的每个值*****
0
60
80
100
*****求列表数字总和*****
240
*****求1-100和*****
5050
*****for循环常见用法-enumerate:既要每个元素的值也要每个元素对应的索引*****
0 1
1 4
2 7
3 10
4 13
5 16
6 19
*****for循环常见用法-zip:同时遍历两个可迭代对象*****
1 4
2 5
3 6
*****continue:计算1-100的偶数和*****
2550
*****break*****
0

demo9-字典与集合

#demo-9
#字典dict与集合set
#dict key:value 键值对 map
scoresDict = {
    "tom":100,
    "david":80,
    "green":60
}
print(scoresDict)
scoresDict["selly"] = 99
print(scoresDict)

print("*****判断key是否在字典里*****")
print("selly" in scoresDict)
print("test" in scoresDict)
print(scoresDict.get("test",999))
print(scoresDict.get("selly",999))#get函数若存在key,则放回value,否则返回自己设置的值
print("*****删除key*****")
print(scoresDict)
scoresDict.pop("tom")
print(scoresDict)

#set无序集合
print("*"*50)
# mySet = set(1,3,4,4,4,4,5,5) #TypeError: set expected at most 1 arguments, got 8
mySet = set([1,3,4,4,4,4,5,5,6,7,8,8,8,9]) #使用列表List创建集合
print(mySet)
print("*****使用add与remove*****")
print(mySet)
mySet.add(999)
print(mySet)
mySet.remove(999)
print(mySet)
print("*****集合交、并、差操作*****")
aSet = set([1,2,3,4])
bSet = set([3,4,5,6])
print(aSet & bSet)
print(aSet | bSet)
print(aSet-bSet)
print(bSet-aSet)
{'tom': 100, 'david': 80, 'green': 60}
{'tom': 100, 'david': 80, 'green': 60, 'selly': 99}
*****判断key是否在字典里*****
True
False
999
99
*****删除key*****
{'tom': 100, 'david': 80, 'green': 60, 'selly': 99}
{'david': 80, 'green': 60, 'selly': 99}
**************************************************
{1, 3, 4, 5, 6, 7, 8, 9}
*****使用add与remove*****
{1, 3, 4, 5, 6, 7, 8, 9}
{1, 3, 4, 5, 6, 7, 8, 9, 999}
{1, 3, 4, 5, 6, 7, 8, 9}
*****集合交、并、差操作*****
{3, 4}
{1, 2, 3, 4, 5, 6}
{1, 2}
{5, 6}

demo10-可变对象与不可变对象

#demo-10
#不可变对象 !!重要

#可变对象
testList = [9,10,6,4,5]
print(testList)
testList.sort()
print(testList)

#不可变对象:对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。
#相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
testStr = "hello world"
print(testStr)
testAnotherStr = testStr.replace("l","L")
print(testStr)
print(testAnotherStr)

[9, 10, 6, 4, 5]
[4, 5, 6, 9, 10]
hello world
hello world
heLLo worLd

demo11-内置函数

#demo-11
#内置函数+函数别名
# abs?
# help(abs)

print(abs(-111))
print(max(1,2,3,4,5,5,3,1,2,4,5,78,))
print(min(1,2,3,4,5,5,3,1,2,4,5,78,))

#类型转换
print(int("123"),type(int("123")))
print(int(12.3))
print(str(123),type(str(123)))

#函数名是指向一个函数对象的引用
myAbs = abs #myAbs相当于函数abs的别名
print(myAbs(-123))

print(hex(65535))
111
78
1
123 <class 'int'>
12
123 <class 'str'>
123
0xffff

demo12-定义函数与isinstance

#demo-12
#定义函数+isinstance

def myAbs(x):
    if not isinstance(x,(float,int)):
        raise TypeError('bad Type') 
    if x>= 0:
        return x
    else:
        return -x

print(myAbs(5))
print(myAbs(0))
print(myAbs(-5))

# print(myAbs(-5,2))#TypeError: myAbs() takes 1 positional argument but 2 were given
# print(myAbs("test"))

#isinstance的用法
print(isinstance(123,int))
print(isinstance(123,float))
print(isinstance("hello wolrd",str))

#函数返回多个值
import random
def getRandomPosition():
    return random.randint(1,10),random.randint(1,10) #其实是返回一个tuple
print(getRandomPosition()[0],getRandomPosition()[1],type(getRandomPosition()))


#求解一元二次方程
import math
def quadratic(a,b,c):
    return (-b+math.sqrt(b**2-4*a*c))/(2*a),(-b-math.sqrt(b**2-4*a*c))/(2*a)
print(quadratic(3,9,2))

5
0
5
True
False
True
5 10 <class 'tuple'>
(-0.24169426078820835, -2.758305739211792)

demo13-默认参数

#demo-13
#函数参数-默认参数

#x**n
def powN(x,n=2): #必选参数在前,默认参数在后/因为在后面才可省略
    if n == 0:
        return 1
    sum = 1
    for each in range(1,n+1):
        sum *= x
    return sum
print(powN(5,5),5**5)
print(powN(8,3),8**3)
print(powN(8)) #若无实际参数,则形式参数n默认为2

def enroll(name,gender,age=6,city="fuzhou"):
    print("name:",name,sep="")
    print("gender:",gender,sep="")
    print("age:",age,sep="")
    print("city:",city,sep="")

print("*"*20)
enroll("xiaoming","F")
print("*"*20)
enroll("xiaoming","F",9)
print("*"*20)
enroll("xiaoming","F",9,"beijing")
print("*"*20)
enroll("xiaoming","F",city="beijing") #可以不按顺序提供默认参数,此时需要把参数名写上
print("*"*20)
enroll("xiaoming","F",city="xiamen",age=15)

3125 3125
512 512
64
********************
name:xiaoming
gender:F
age:6
city:fuzhou
********************
name:xiaoming
gender:F
age:9
city:fuzhou
********************
name:xiaoming
gender:F
age:9
city:beijing
********************
name:xiaoming
gender:F
age:6
city:beijing
********************
name:xiaoming
gender:F
age:15
city:xiamen

demo14-默认参数必须指向不可变对象

#demo-14
#默认参数必须指向不可变对象

def add_end(L=[]):
    L.append('END')
    return L

tempList = [1,2,3]
add_end(tempList)
add_end()
print(tempList)
#ython函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[]
#每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了
add_end()
add_end()
add_end()
print(add_end())

#改进
def add_end(L=None):
    if L is None:
        L = []
    L.append("END")
    return L
add_end()
add_end()
add_end()
print(add_end())

[1, 2, 3, 'END']
['END', 'END', 'END', 'END', 'END']
['END']

demo15-可变参数

#demo-15
#可变参数
#计算a2 + b2 + c2 + ……

#定义可变参数仅在参数前加*
#在函数内部,可变参数为一个tuple元组
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

print(calc(1,2,3,4))
tempList = [1,2,3,4]
print(calc(tempList[2],tempList[3]))
print(calc(*tempList))  #若原本存在列表,则在其前面加*即可把列表或者元组的元组变为可变参数传入
30
25
30

demo16-关键字参数与命名关键字参数

#demo-16
#关键字参数与命名关键字参数

#关键字参数
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
    
person("Tom",20)
person("Tom",20,city="fuzhou",gender="F")

myDict = {"city":"xiamen","tel":13000000000,"gender":"F"}
person("Tom",20,**myDict)

print("*"*50)
#和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数
#此时命名关键字参数则必须存在,且命名关键字参数必须传入参数名
def person(name, age, *, city, job):
    print(name, age, city, job)
person("Tom",20,city="fuzhou",job="none")

#如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
def person(name, age, *args, city, job):
    print(name, age, args, city, job)
person("Tom",25,*[1,2,3,4],city="fuzhou",job="none")

#命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
def person(name, age, *, city='Beijing', job):
    print(name, age, city, job)

person("Tom",20,job="none")

#

name: Tom age: 20 other: {}
name: Tom age: 20 other: {'city': 'fuzhou', 'gender': 'F'}
name: Tom age: 20 other: {'city': 'xiamen', 'tel': 13000000000, 'gender': 'F'}
**************************************************
Tom 20 fuzhou none
Tom 25 (1, 2, 3, 4) fuzhou none
Tom 20 Beijing none

demo17-函数参数顺序

#demo-17
#参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
#注意是先命名关键字参数后关键字参数,因为命名关键字参数需要指定参数名,而关键字参数抛在最后即可
#可变参数在中间,因为前面是位置参数或默认参数,按位置进行解析,后面为关键字参数需要指定key,中间剩余的则为可变参数

#arg为可变参数;kw为关键字参数
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

    
f1(100,200)
f1(1,2,3,*[1,2,3,4,5])
f1(1,2,3,*[1,2,3,4,5],city="fuzhou",gender="F",job="None")

#无可变参数,d为命名关键字参数,kw为关键字参数;注:关键字参数在命名关键字参数后面,大杂烩
def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
    
f2(1,2,3,d="dddd",city="fuzhou",gender="F",job="None") #d为命名关键字参数,必须指定该参数值,否则报错
f2(1,2,3,d="dddd") 
a = 100 b = 200 c = 0 args = () kw = {}
a = 1 b = 2 c = 3 args = (1, 2, 3, 4, 5) kw = {}
a = 1 b = 2 c = 3 args = (1, 2, 3, 4, 5) kw = {'city': 'fuzhou', 'gender': 'F', 'job': 'None'}
a = 1 b = 2 c = 3 d = dddd kw = {'city': 'fuzhou', 'gender': 'F', 'job': 'None'}
a = 1 b = 2 c = 3 d = dddd kw = {}

demo18-random常见函数

#demo-18
#random常见函数
import random

print( random.randint(1,10) )        # 产生 1 到 10 的一个整数型随机数  [1,10]
print( random.random() )             # 产生 0 到 1 之间的随机浮点数[0,1)
print( random.uniform(1.1,5.4) )     # 产生  1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print( random.choice('tomorrow') )   # 从序列中随机选取一个元素
print( random.choice([1,2,3]) )   # 从序列中随机选取一个元素
print( random.randrange(1,100,2) )   # 生成从1到100的间隔为2的随机整数

a=[1,3,5,6,7]                # 将序列a中的元素顺序打乱
random.shuffle(a)
print(a)
# random.uniform?
1
0.5632331524744293
2.7294567751257137
r
2
3
[5, 7, 6, 1, 3]

demo19-切片

#demo-19
#切片slice
testList = ["fujian","anhui","shanghai","beijing","shenzhen"]
print(testList[:3]) #左闭右开
print(testList[1:3])
print(testList[-2:-1]) #反向
print(testList[-2:])

testList = list(range(1,101))
print(testList)
print(testList[:10])  #前10个
print(testList[-10:]) #后10个
print(testList[:10:2])  #前10个,步长为2
print(testList[::5])   #间隔5个取一个


#重要;注意对比
#引用与复制
print("*"*50)
testList = ["fujian","anhui","shanghai","beijing","shenzhen"]
tempList = testList   #tempList与testList均指向同一个list[]
print(tempList)
testList.append("test")
print(tempList)
print("*"*50)
testList = ["fujian","anhui","shanghai","beijing","shenzhen"]
tempList = testList[:]  #拷贝;重新复制
print(tempList)
testList.append("test")
print(tempList)
print("*"*50)
print("hello world"[::2]) #字符串也可以当作一个list进行切片处理

['fujian', 'anhui', 'shanghai']
['anhui', 'shanghai']
['beijing']
['beijing', 'shenzhen']
[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]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
[1, 3, 5, 7, 9]
[1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76, 81, 86, 91, 96]
**************************************************
['fujian', 'anhui', 'shanghai', 'beijing', 'shenzhen']
['fujian', 'anhui', 'shanghai', 'beijing', 'shenzhen', 'test']
**************************************************
['fujian', 'anhui', 'shanghai', 'beijing', 'shenzhen']
['fujian', 'anhui', 'shanghai', 'beijing', 'shenzhen']
**************************************************
hlowrd

demo20-可迭代对象Iterable

#demo-20
#可迭代对象
myDict = {'a': 1, 'b': 2, 'c': 3}
for key in myDict:#默认迭代key
    print(key,myDict[key])
    
for value in myDict.values():#迭代value
    print(value)

for key,value in myDict.items(): #迭代键值对
    print(key,value)
    
for each in list(range(1,5)):
    print(each)
    
for eachChar in "hello":
    print(eachChar)

print("*****判断是否为可迭代对象*****")
from collections.abc import Iterable
print(isinstance([1,2,23],Iterable))
print(isinstance(5,Iterable))
print("*****enumerate*****")
for index,value in enumerate(["a","b","c"]):
    print(index,value)

a 1
b 2
c 3
1
2
3
a 1
b 2
c 3
1
2
3
4
h
e
l
l
o
*****判断是否为可迭代对象*****
True
False
*****enumerate*****
0 a
1 b
2 c

demo21-列表生成式

#demo-21
#列表生成式List Comprehensions

print([i*i for i in range(1,11)])
print([i*i for i in range(1,11) if i % 2 == 0]) #只有偶数 
print([x + y  for x in [1,2,3] for y in [4,5,6]]) #注意该种用法

L = ['Hello', 'World', 'TEST', 'XYZ']
print([each.lower() for each in L])

print( [x if x % 2 == 0 else -x for x in range(1, 11)])

L = ['Hello', 'World',999, 'TEST', 'XYZ']
print([each.lower() for each in L if isinstance(each,str)])

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[4, 16, 36, 64, 100]
[5, 6, 7, 6, 7, 8, 7, 8, 9]
['hello', 'world', 'test', 'xyz']
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
['hello', 'world', 'test', 'xyz']

demo22-生成器

#demo-22
#生成器
#若列表元素规模大,则一次占用过多内存
#因此可以使用生成器generator,在循环的过程中计算元素值
L = [x * x for x in range(10)]
print(L,type(L))

g = (x * x for x in range(10)) #把[]替换为()即为generator生成器
print(g,type(g))

for each in g:#遍历生成器
    print(each)
    
    
#斐波拉契数列
#如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数
#1 1 2 3 5 8
def fib(n):
    i,left,right = 0,0,1 
    while(i<n):
        yield(right)
        left,right = right,left+right
        i += 1
        
for each in fib(10):
    print(each)

#调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。
print(next(fib(5)))
print(next(fib(5)))
print(next(fib(5)))

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] <class 'list'>
<generator object <genexpr> at 0x000001E22B2B5BC8> <class 'generator'>
0
1
4
9
16
25
36
49
64
81
1
1
2
3
5
8
13
21
34
55
1
1
1

demo23-迭代器

#demo-23
#迭代器

#可以直接用于for循环:
#①生成器generator 与 带yield的generator function
#②集合数据类型:list tuple dict set str

print("*****判断是否为可迭代对象Iterable*****")
from collections.abc import Iterable
print(isinstance([],Iterable))
print(isinstance("",Iterable))
print(isinstance((),Iterable))
print(isinstance({},Iterable))
print(isinstance(5,Iterable))


#生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator
#可以使用iter()函数将Iterable变为Iterator
print("*****判断是否为迭代器对象Iterator*****")
from collections.abc import Iterator
print(isinstance([],Iterator))
print(isinstance(iter([]),Iterator)) #使用iter函数变为迭代器
print(isinstance("",Iterator))
print(isinstance((),Iterator))
print(isinstance({},Iterator))
print(isinstance(5,Iterator))
print(isinstance(fib(10),Iterator))

#Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误
#可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据
#所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
#Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的

*****判断是否为可迭代对象Iterable*****
True
True
True
True
False
*****判断是否为迭代器对象Iterator*****
False
True
False
False
False
False
True

demo24-map与reduce函数

#demo-24
#高阶函数之map与reduce
#一个函数就可以接收另一个函数作为参数

#变量可以指向函数
myAbs = abs  #函数名是指向函数的变量
print(myAbs(-10))

#高阶函数
def add(x,y,f):  #接收另一个函数作为参数
    return f(x)+f(y)

print(add(-5,-8,abs))


#map函数
#map函数接收两个参数,一个是函数,另一个是Iterable
#map将函数依次作用到可迭代对象的每个元素上
#并把结果作为新的Iterator返回

def mySqure(x):
    return x**2

print(list(map(mySqure,[1,2,3,4]))) #将iterator转换为list;把函数mySqure作为参数传入map
print(list(map(str,[1,2,3,4])))

print(list(map(lambda x:x.lower(),['adam', 'LISA', 'barT'])))
print(list(map(str.lower,['adam', 'LISA', 'barT'])))  #str.lower



#reduce函数
#reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
#把结果和序列的下一个元素进行运算
from functools import reduce

def fn(x,y):
    return 10 * x + y
print(reduce(fn,[1,3,5,7,9]))

10
13
[1, 4, 9, 16]
['1', '2', '3', '4']
['adam', 'lisa', 'bart']
['adam', 'lisa', 'bart']
13579

demo25-filter函数

#demo-25
#filter函数:用于过滤序列
#和map()类似,filter()也接收一个函数和一个序列。
#和map()不同的是,filter()把传入的函数依次作用于每个元素
#然后根据返回值是True还是False决定保留还是丢弃该元素。

def is_odd(x):
    return x % 2 == 1

#注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,
#所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。
print(list(filter(is_odd,list(range(1,12)))))

#回数
def is_palindrome(x):
    if str(x) == str(x)[::-1]:  #[::-1]倒序
        return True
print(list(filter(is_palindrome,list(range(1,1000)))))

[1, 3, 5, 7, 9, 11]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]

demo26-sorted函数

#demo-26
#sorted:key参数接收函数作为排列依据

tempList = [36, 5, -12, 9, -21]
print(tempList)
print(sorted(tempList)) #不改变原始列表
print(tempList)
tempList.sort() #排列原始列表
print(tempList)


tempList = [36, 5, -12, 9, -21]
print(sorted(tempList,key=abs)) #key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序
print(sorted(tempList,key=abs,reverse=True)) #反向

[36, 5, -12, 9, -21]
[-21, -12, 5, 9, 36]
[36, 5, -12, 9, -21]
[-21, -12, 5, 9, 36]
[5, 9, -12, -21, 36]
[36, -21, -12, 9, 5] 

demo27-匿名函数lambda

#demo-27
#匿名函数lambda
#无需显式定义函数,使用匿名函数更为方便

print(list(map(lambda x:x.lower(),['adam', 'LISA', 'barT'])))


def mySqure(x):
    return x**2
print(list(map(mySqure,[1,2,3,4])))
print(list(map(lambda x:x**2,[1,2,3,4])))


def is_odd(x):
    return x % 2 == 1
print(list(filter(is_odd,list(range(1,12)))))
print(list(filter(lambda x:x%2==1,list(range(1,12)))))

#匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
f = lambda x:x**2
print(f(5))

['adam', 'lisa', 'bart']
[1, 4, 9, 16]
[1, 4, 9, 16]
[1, 3, 5, 7, 9, 11]
[1, 3, 5, 7, 9, 11]
25

demo28-类和实例

#demo-28
#类和实例

class Student(object):  #定义类->相当于模板
    pass 

std1 = Student()  #类的实例化->对象
std2 = Student()

print(std1)
print(std2) #每个实例有不同的内存地址
print(Student)

std1.socre = 99  #可以自由的给实例绑定变量
print(std1.socre)

#类起到模板作用,可以设置初始化实例时必须的参数
class StudentV1(object):
    
    def __init__(self,name,age):  #self指向对象本身
        self.name = name
        self.age = age
        
# std1 = StudentV1() #报错:TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
std1 = StudentV1("Tom",6)
print(std1.name,std1.age) #打印对象属性;但该种方法不好,直接访问了数据;
<__main__.Student object at 0x000001E22B27D648>
<__main__.Student object at 0x000001E22B24D6C8>
<class '__main__.Student'>
99
Tom 6

demo29-数据封装

#demo-29
#数据封装

#对对象属性或数据的访问应该通过调用类的方法进行
#从而实现对数据的封装,避免从外部访问对象的数据

class StudentV2(object):
    
    def __init__(self,name,age):  #self指向对象本身
        self.name = name
        self.age = age
    
    def printScore(self):
        print(self.name,self.age)
        
    def isAdult(self):
        if self.age >= 18:
            print("Adult")
        else:
            print("hhh")

std1 = StudentV2("Tom",6)
std1.printScore() #通过method方法访问对象内部数据
std1.isAdult()
Tom 6
hhh

demo30-访问限制

#demo-30
#访问限制

class StudentV2(object):
    
    def __init__(self,name,age):  #self指向对象本身
        self.name = name
        self.age = age
    
    def printScore(self):
        print(self.name,self.age)
        
    def isAdult(self):
        if self.age >= 18:
            print("Adult")
        else:
            print("hhh")

std1 = StudentV2("Tom",6)
std1.isAdult()
std1.age = 20  #外部可以直接操作对象内部的数据
std1.isAdult()

#可以在实例变量名前加上__(两个下划线),从而将变量变为私有变量
#数据封装, 此时数据只能内部访问,无法外部访问
#__varName__以双下划线开头与结尾的是特殊变量,因此不使用该种命名方式


class StudentV3(object):
    
    def __init__(self,name,age):  #self指向对象本身
        self.__name = name
        self.__age = age
        
    def printScore(self):
        print(self.__name,self.__age)
        
    def isAdult(self):
        if self.__age >= 18:
            print("Adult")
        else:
            print("hhh")
            
    def getScore(self):
        return self.__age
    
    def setScore(self,age):  #采用数据封装的方式,内部方法可以对传入的参数进行更多的操作
        
        if 0 <= age and age<=100: #0 <= score and <=100
            self.__age = age
        else:
            raise ValueError("value error")
            
std1 = StudentV3("Tom",6)
# print(std1.__age)  #'StudentV3' object has no attribute '__age' #此时从外部无法访问__age
std1.printScore()
print(std1.getScore())
std1.setScore(20)
print(std1.getScore())


#从外部其实也可以直接方法私有变量 : _ClassName__VarName
print(std1._StudentV3__age)  #Python解释器对外把__name变量改成了_Student__name

std1.__age = 999 #所以这种方法只是增加了一个__age变量,但并非更改了类内属性__age
print(std1.getScore(),std1.__age) #可以发现类内属性_age并未改成999,因为此时该变量全称变为_StudentV3__age
hhh
Adult
Tom 6
6
20
20
20 999

demo31-继承与多态

#demo-31
#继承与多态
#多态:为不同数据类型的实体提供统一的接口

class Animal(object):
    def run(self):
        print('Animal is running...')
        
class Dog(Animal):  #继承于Animal类
    def eat(self):
        print('Eating meat...')
        
    def run(self):
        print('dog is running...')
        
class Cat(Animal):
    def run(self):
        print('cat is running...')

dog = Dog()
dog.run()  #当子类与父类存在同样的方法时,子类会覆盖父类的方法->多态
dog.eat()

cat = Cat()
cat.run()

#既是子类也是父类
print(isinstance(dog,Animal))
print(isinstance(dog,Dog))

def run_twice(animal):
    animal.run()
    animal.run()
    
run_twice(Animal())
run_twice(Dog())
run_twice(Cat())
dog is running...
Eating meat...
cat is running...
True
True
Animal is running...
Animal is running...
dog is running...
dog is running...
cat is running...
cat is running...

demo32-字符串

#demo1-字符串

print("*****str.title()*****")
myStr = "hello world"
print(myStr)
print(myStr.title())#单词首字母大写

print("*****upper()与lower()*****")
myStr = "hello world"
print(myStr)
print(myStr.upper())  #全部大写
myStr = "HELLO WORLD"
print(myStr.lower())  #全部小写
print(myStr)          #使用lower()并不会修改字符串对象的数据,只是重新传回一个新字符串,这是因为str为不可变对象

print("*****合并字符串*****")
firstStr = "hello"
lastStr = "world"
print(firstStr + lastStr)   #采用+连接字符串中间无空格
print(firstStr + " " + lastStr)

print("*****删除空白****")
testStr = "Python "
print(len(testStr))
print(len(testStr.rstrip()) )#返回的只是新对象,并非在testStr对象上修改数据
print(len(testStr))          #长度仍为7
testStr = testStr.rstrip()   #有效修改
print(len(testStr))          #长度仍为6

#rstrip lstrip strip
testStr = " Python "
print(len(testStr))    #8
testStr = testStr.strip()   
print(len(testStr))    #6      


#彩蛋-Python之禅
import this
*****str.title()*****
hello world
Hello World
*****upper()与lower()*****
hello world
HELLO WORLD
hello world
HELLO WORLD
*****合并字符串*****
helloworld
hello world
*****删除空白****
7
6
7
6
8
6
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

demo33-列表del/remove/reverse 

#demo2-列表

print("*****采用del删除列表元素*****")
testList = ["a","b","c","d"]
print(testList)
del testList[0]  #采用del删除后,无法再访问该值
print(testList)

print("*****采用pop()删除列表元素*****")
testList = ["a","b","c","d"]
print(testList)
testList.pop() #默认删除最后一个元素
print(testList)
temp = testList.pop(1) #接收被弹出的元素/参数为删除元素的索引
print(testList)
print(temp)  


print("*****根据值删除元素remove()*****")
testList = ["a","b","c","d","a","b","c","d"]
print(testList)
testList.remove("a") #只删除第一个指定的值
print(testList)

print("*****反转列表*****")
testList = ["a","b","c","d"]
print(testList)
testList.reverse()          #永久性修改列表
print(testList)
testList = testList[::-1] #[::-1]反转
print(testList)

*****采用del删除列表元素*****
['a', 'b', 'c', 'd']
['b', 'c', 'd']
*****采用pop()删除列表元素*****
['a', 'b', 'c', 'd']
['a', 'b', 'c']
['a', 'c']
b
*****根据值删除元素remove()*****
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
['b', 'c', 'd', 'a', 'b', 'c', 'd']
*****反转列表*****
['a', 'b', 'c', 'd']
['d', 'c', 'b', 'a']
['a', 'b', 'c', 'd']

demo34-删除包含特定值的所有列表元素 

#demo3-删除包含特定值的所有列表元素
#for循环中不应该修改可迭代对象,否则难以跟踪其中的元素
#若要在遍历的同时修改可迭代对象,可使用while循环

testList = ["a","b","c","d","a","b","c","d"]
print(testList)
while "a" in testList:
    testList.remove("a") 
print(testList)

['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
['b', 'c', 'd', 'b', 'c', 'd']

demo35-可变对象(列表、字典)作为函数参数

#demo4-可变对象(列表、字典)作为函数参数
#python的参数,如果传递的是不可修改变量则无法改,可变变量则可以改
#如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值
#如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象

def modifyList(testList):
    testList.append("test")

print("*****函数修改可变对象*****")
myList = [1,2,3,4]
print(myList)
modifyList(myList) #对传入的可变对象的修改是永久性的
print(myList)

print("*****禁止函数修改可变对象*****")
myList = [1,2,3,4]
print(myList)
modifyList(myList[:]) #传入副本,不修改原始对象;尽量避免,尤其是大列表,耗时与费内存
print(myList)
*****函数修改可变对象*****
[1, 2, 3, 4]
[1, 2, 3, 4, 'test']
*****禁止函数修改可变对象*****
[1, 2, 3, 4]
[1, 2, 3, 4]

猜你喜欢

转载自blog.csdn.net/zsllsz2022/article/details/126689381
今日推荐