python基础

1.变量以及数据类型

数据类型

Numbers 数字:

int(有符号整型)long(长整型[也可以表示八进制和十六进制],python3里已经废弃了)float(浮点型) complex(复数)

布尔类型 bool : Ture False

String(字符串)

空值 None

List(列表)——>shuzu----[]

Tuple(元祖)——>()

Dictionary(字典)——>{}

集合类型

进制转换:

使用代码进行进制转换:详见下列代码

a = 12
print(bin(a))  #0b1100
print(oct(a))  #0o14
print(hex(a))  #0xc

使用bin内置函数可以将数字转换成二进制

使用oct内置函数可以将数字转换成八进制

使用hex内置函数可以将数字转换成十六进制

 

在python里,变量是没有数据类型的,我们所说变量的数据类型,其实是变量对应的值的数据类型,不需要定义变量,直接是动态的,会随时修改的

标识符关键字

标识符:

变量,模块名,函数名,类名

标识符的命名规则:

  1. 由数字、字母和_下划线组成,不能以数字开头

  2. 严格区分大小写(计算机编程里,一共52个英文字母,26大写+26小写)

  3. 不能使用关键字(在python语言里有特殊含义的单词)作为变量名

保留字

12345
and elif import raise global
as else in return nonlocal
assert exept is try True
break finally lamda while False
class for not with None
continue form or yield  
def if pass del  

 

规范:建议遵守,遵守规范会显得专业,并且代码易读

  1. 做到顾名思义

  2. 遵守一定的命名规范

    1. 小驼峰命名法:第一个单词的首字母小写,以后每个单词的首字母都大写

    2. 大驼峰命名法:每个单词的首字母都大写

    3. 使用下划线连接

    在python里的变量、函数和模块名都使用下划线连接;

    python里的类名使用大驼峰命名法

输出语句

print

#输出
a = 32
b = 'hello'
c = True
d = ['zjlun','zhansn']
print(type(a))
print(type(b))
print(type(c))
print(type(d))
print(type(3.14))

 

sep 参数用来表示输出时,每个值之间用哪种字符作为分隔。默认使用空格,修改方式如下

我 = '张三'
print(我)
print('hello','good','yes','hi')
print('hello','good','yes','hi',sep='+')

 

end 当执行完一个print语句以后,接下来要输出的字符。默认为\n表示换行,修改方式如下

print('hello','good','yes','hi',end = '\t')
print('hello','good','yes','hi',end = '————————————')
print('hello','good','yes','hi')

 

 

 

输入

input

input() ==> 括号里写提示信息

定义一个变量可以保存用户输入的内容,如下

#输入

input("请输入您的密码:")

password = input("请输入您的密码:")
print(password)

注意:不管用户输入的是什么,变量保存保存的结果都是字符串

类型转换

将一个类型的数据转换为其他类型数据

age = input('请输入您的年龄:')
#print(age + 1)   error
#原因:input 接收到的用户输入都是 str 字符串类型
#在python里,如果字符串和数字做加法运算,会直接报错
#把字符串类型的变量 age 转换成为数字类型的 age
print(type(age))
#使用 int 内置类可以将其他类型的数据转换为整数
age = int(age) + 1
print(type(age))
#转换数据类型的原因:不同的数据类型进行运算时的运算规则是不一样的
#转化为整数
a = '31'
print(a) #输出31,但这个31是字符串类型
#如果字符串不是合法的数字,将字符串转换成int会直接报错
x = 'hello'
y = int(x)
print(y)

x = '1a2c'
y = int(x,16)#将字符串当做16进制数转换
#只能包含A-F

m = '12'
n = int(m,8)
print(n) # 10
#转化为浮点数
a = '12.34'
#使用内置float类可以将其他类型数据转换成为float浮点数
b = float(a)
print(b+1)

c = 101
print(float(c))

print(float('12'))#将字符串转换成浮点数     12
print(float(12))#将整型数字转换成浮点数     12
#转换成为字符串
#使用 str 内置类可以将其他类型数据转换成为字符串
a = 34
b = str(a)
print(a,b)# 34 34 前一个是int 后一个是字符串

转换为布尔值

#使用bool内置类可以将其他数据类型转换成布尔值
print(bool(100))#将1数字100转换成布尔值   True
print(bool(-1))#True
print(bool(0))#False
#数字非零都是True

#字符串转布尔类型
print(bool('hello'))# True
print(bool('False'))#True
print(bool(''))#False
#空字符串 ''/"" 才能转换为False,其他字符串都是True

#None空数据 转换为布尔值是 False
print(bool(None))#False

#[]空列表
print(bool([]))#False

#()空元组
print(bool(()))#False

#空集合
s = set()
print(bool)

#在Python中,只有空字符串'',"",数字0,空字典{},空列表[],空元组(),空数据None会被转换为False
#其他的都会转换为True

#在计算机里,True和False其实就是使用数字 1 和 0来保存的
print(True + 1) # 2
print(False + 1)# 1

运算符

#算术运算符在数字里的使用

** 幂运算
**等价于^,例如2 * *10=1024
  开平方:
print(81 ** (1/2))
  **=
   
   
// 整除
print(10 /  3) #3.333333333
print(10 // 3) #3
//=

#除法
#在Python 3里,两个整数相除,得到的结果会是浮点数 10/3——>3.333333
#在Python 2里,两个整数相除,得到的结果会是一个整数 10/3——>3

print(6/2) # 3.0
print(9/2) # 4.5
#算术运算符在字符串里的使用
#字符串里支持的算术运算符有限,只支持加法和乘法
#加法运算符:只能用于两个字符串拼接,数字和字符串之间不能做加法运算
#乘法运算符:只能用于数字和字符串之间,用来将一个字符串重复多次
print('hello' * 2) #hellohello
m,n = 3,5   #拆包
print(m,n) # 3 5

x = 'hello','good','yes' #元组,()可以省略
print(x) #('hello','good','yes')

#拆包时,变量的个数和值的个数不一致会报错,不能多也不能少
# y,z = 1,2,3,4,5 #有太多的值要解包了 error
# print(y,z)
#o,p,q = 4,2 #拆包的值不够 err
#print(o,p,q)

o,*p,q = 1,2,3,4,5,6 # *p是可变长度,把1给o,6给q,[2,3,4,5]给p
print(o,p,q) # 1 [2,3,4,5] 6

*o,p,q = 1,2,3,4,5,6 # *o是可变长度,把6给q,5给p,[1,2,3,4]给o
print(o,p,q) # [1,2,3,4] 5 6
o,p,*q = 1,2,3,4,5,6 # *q是可变长度,把1给o,2给p,[3,4,5,6]给q
print(o,p,q) # 1 2 [3,4,5,6]
#比较运算符
#字符串之间使用比较运算符,会根据各个字符的ASCII码值逐一进行比较
print('a'>'b') #False
print('abc'>'b')#False 979899 > 98 是97和98比较,这就是逐一比较的意思

#数字和字符串之间,做 == 运算的结果是False,做!=运算的结果是True,不支持其他的比较运算
print('a' == 90)#False
print('a' != 97)#True
print('a' > 90)#error
#逻辑运算符
   # 逻辑与 and 逻辑或 or 逻辑非 not
   print(2 >1 and 5 > 3 and 10 > 2)
   #逻辑与运算做取值时,取第一个为False的值;如果所有的运算数都是True,取最后一个值
   print('good' and 'yes' and 'ok' and 100)#100
   #逻辑或运算做取值时,取第一个为True的值;如果所有的运算数都是False,取最后一个值
   print(0 or [] or {} or ())#()
#位运算符与C语言相同
#运算符的优先级
逻辑运算符的优先级:not > and >or
强烈建议:在开发中,使用括号来说明运算符的优先级
#python不支持switch……case语句
——————————————————————————————————————————————————————————————————————————————

#if结构:
if 条件判断:
条件成立时执行的代码,前方有缩进
   
 
例子:
age = int(input("请输入你的年龄:"))#注意:这里input得到的是字符串,不能和数字比较,
#需要类型转换
if age < 18:
   print('未满18岁禁止入内')
   
——————————————————————————————————————————————————————————————————————————————
#if……else结构
if 条件判断:
条件成立时执行的代码
else
条件不成立时执行的代码
#注意:if和else后面都要跟:冒号
# 下方要执行的代码需要有缩进

age = int(input("请输入你的年龄:"))
if age < 18:
   print('未满18岁禁止入内')
else:
   print('请进')
——————————————————————————————————————————————————————————————————————————————
score = int(input('请输入你的分数\n'))
if 60 > score >= 0:
   print('不及格')
elif 80 > score >= 60: #这里的 elif 是else if 的意思,但Python不支持写else if
   print('良好')
elif 90 > score >= 80:
   print('优秀')
elif 100 >= score >=90:
   print('真棒')
else:
   print('请输入正确的分数')
—————————————————————————————————————————————————————————————————————————————— # Python语言里,使用强制缩进来表示语句间的结构
#pass 关键字在Python里没有意义单纯的用来占位,保证语句的完整性
例子:
age = int(input('请输入您的年龄:'))
if age > 18:
   pass #这里pass用来占位,但这条语句没有含义,如果缺少了pass就会报错
print('hello')
#三元表达式

num1 = int(input('请输入一个数字:'))
num2 = int(input('请再输入一个数字:'))

x = num1 if num1 > num2 else num2
'''
等价于
if num1 > num2:
x = num1
else:
x = num2
'''

print('两个数里的较大数是',x)

循环

python里不支持do……while循环
python里也没有自增自减运算符

#while循环
x = 10
while x < 10:#注意这里也有:冒号
   print('hello')
   x++
   
#for···in 循环
Python的for循环指的是for……in 循环
#for……in循环格式:
for x in [1,2,3,4,5,6,7,8,9] #注意:in后面必须要是一个可迭代对象!!!
#目前接触的 可迭代对象:字符串、列表、字典、元组、集合、range

#range 内置类用来生成指定区间的整数序列(列表)
#range 生成的是左开右闭区间
for x in range(1,11):
   print(x)#输出1-10
等价于:for x in [1,2,3,4,5,6,7,8,9,10]:
   print(x)

用for……in循环打印1到100的和:
for x in range(1,101):
   z +=j
print(z)    

break和continue

#break和continue在Python里只能用于循环语句中

#break用来结束整个循环

#continue用来结束本轮循环,开启下一轮循环

嵌套循环

外循环控制行数,内循环控制列数

for……else
for……else语句:当循环里break没有被执行的时候,就会执行else

字符串

字符串的表示方式

字符串是不可变数据类型,对于字符串的任何操作,都不会改变原有的字符串
#在python里,可以使用一对单引号、一对双引号、一对三个双引号、一对三个单引号都可以表示字符串
#如果字符串里面还有双引号,外面就可以使用单引号

#字符串的转义字符 \
x = 'I\'m xiaoming' # \ 表示的是转义字符,作用是对 \ 后面的字符进行转义
——————————————————————————————————————————————————————————————————————————————
#字符串的下标和切片

# 下标我们又称之为索引,表示第几个数据
str list tuple 可以通过下标来获取或操作数据
下标都是从0开始的

Word = ’zhangsan'
print(word[4])
#字符串是不可变数据类型,对于字符串的任何操作,都不会改变原有的字符串
——————————————————————————————————————————————————————————————————————————————
#切片
#切片就是从字符串中复制一段指定的内容,生成一个新的字符串
m = 'abcdefghijklmnopqrstuvwxyz'
print(m[5])#m[index] ==> 获取指定下标上的数据
#切片语法   m[stard:end:step]
#也是左闭右开区间
#step指的是步长,理解为在指定区间内,每step个取一次

print(m[2:9])#cdefghi ==>[2,9)
print(m[2:])#如果只设置了start,后面默认到最后   cdefghijklmnopqrstuvwxyz
print(m[:9])#如果只设置了end,会从头开始取值     abcdefghi
#步长默认为1
print(m[2:9:2])#步长为2,                         cegi
#步长不能为0,但可以为负数
print(m[3:15:-1])#打印的是空的,-1是从右往左找,从下标为3的地方往左找下标为15
print(m[15:3:-1])#注意:这里包含15,不包含3         ponmlkjihgfe
print(m[::])#从左往右全部复制一份
print(m[::-1])#从右往左全部复制一份
#stard和end为负数表示从右往左数
print(m[-5:-9])#空
print(m[-9:-5])#rstu   注意:这里步长为1是正数,从左往右取

字符串的常见操作

x = 'abcdefghijklmnopqrstuvwxyz'

#获取字符串的长度
#使用内置类len
print(len(x))#26

#查找内容相关方法
#find/index/rfind/rindex
#可以获取指定字符的下标
#s.find(sub[,start[,end]]) -> int 返回的一定是一个int值
print(x.find('l')) #11

print(x.index('l')) #11

#find和index的区别:
print(x.find('P'))  #-1 如果字符在字符串里不存在,结果是-1
print(x.index('P')) # ValueError: substring not found   字符在字符串里不存在会报错
#使用find,如果字符在字符串里不存在,会返回-1
#使用index,如果字符在字符串里不存在,会直接报错

#find用法2:
print(x.find('l',4,9))#在下标4到9的范围内寻找字符'l'

'''
s.find(sub[, start[, end]]) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within s[ start: end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.

s.find(sub [,start [,end]])-> int
返回S中找到子字符串sub的最低索引,
这样sub包含在s [start:end]中。可选的
参数start和end被解释为切片表示法。
失败时返回-1。
'''
#rfind和rindex都是找最大的下标,它们和find,index它们的区别与find和index的区别是一样的

# startswith,endswith, isalpha,isdigit, isalnum, isspace
# is开头的是判断,结果是一个布尔类型
print('he1lo'.startswith('he')) #True   startswith 判断字符串是不是以括号里面的字符为开头
print('hello'.endswith('o'))    #True   endswith   判断字符串是不是以括号里面的字符为结尾
print('hello'.isalpha())# True 判断字符串是不是都字母     alpha字母
print('123'.isdigit())#True     判断字符串是否都是正整数   digit数字
#alnum判断字符串是否由正整数或字母组成
print('ab123hello'.isalnum())#True
print('123'.isalnum())#True
print('abhello'.isalnum())#True
print('4 - 1'.isalnum())#False
print('   '.isspace())#True是否全部由空格组成
'''

计算出现次数:count
返回 str 在start和end之间在mystr里面出现的次数
语法格式:
s.count(sub[,start[,end]]) -> int
示例:
mystr = '今天天气好晴朗,处处好风光'
print(mystr.count('好')) #3 '好'出现了三次
'''

"""
#替换内容:replace
替换字符串中指定的内容,如果指定次数count,则替换不会超过count次
mystr ='今天天气好晴朗,处处好风光呀好风光'
newstr = mystr.replace('好','坏')
print(mystr)#今天天气好晴朗,处处好风光呀好风光 原字符串未改变!
print(newstr)#今天天气坏晴朗,处处坏风光呀坏风光得到的新字符串里,'好'被修改成了'坏'

newstr = mystr.replace('好',坏',2)#指定了替换的次数
print(newstr)#今天天气坏晴朗,处处坏风光呀好风光只有两处的‘好被替换成了‘坏
"""
#切割字符串split,rsplit,splitlines,partition,rpartition
#字符串类型的数据
x = 'zhangsan-lisi-wnagwu-jerry-henry-merry-jack-tony'
#['zhangsan','lisi','wangwu','jerry','henry','merry','jack','tony']
#使用split方法,可以将一个字符串切割成一个列表
y = x.split('-')
print(y)    #切割以后的结果就是一个列表['zhangsan','lisi','wangwu','jerry','henry','merry','jack','tony']
#rsplit
z = x.rsplit('-')#从右往左切
print(z)#['zhangsan','lisi','wangwu','jerry','henry','merry','jack','tony']
#print(x.split('-',2))的2是分割两次的意思,2控制分割次数,不写默认全部分割
print(x.split('-',2))#['zhangsan', 'lisi', 'wnagwu-jerry-henry-merry-jack-tony']
print(x.rsplit('-',2))#['zhangsan-lisi-wnagwu-jerry-henry-merry', 'jack', 'tony']

#splitlines 按照行分隔,返回一个包含各行作为元素的列表
#partition 指定一个字符串作为分隔符,分为3部分
# 字符前面   字符   字符后面  

print('acdefXmpXqwrst'.partition('X')) #('acdef', 'X', 'mpXqwrst')
print('acdefXmpXqwrst'.rpartition('X')) #('acdefXmp', 'X', 'qwrst')

#获取文件名和后缀名
file_name = '不要打开.mp4'
print(file_name.rpartition('.')) #('不要打开', '.', 'mp4')

#修改大小写capitalize,title,upper,lower
#空格处理ljust,rjust,center,lstrip,rstrip,strip
#字符串拼接:join

字符集

#字符集
#ASCII-->Latin 1-->Unicode编码
print(ord('a')) #97
print(chr(65))  #A

print(ord('你'))#20320
print(ord('我'))#25105
print(ord('爱'))#29233
#这里是Unicode编码哦
print(chr(25105),chr(29233),chr(20320))

#编码集
#GBK   国标扩     汉字占两个字节     简体中文   也就是GB2312
#BIG5   繁体中文
#utf-8 统一编码   汉字占三个字节

#使用encode字符串转换成指定编码集结果
print('你'.encode('gbk'))    #b'\xc4\xe3'       50403   11000100 11100011
print('你'.encode('utf8'))   #b'\xe4\xbd\xa0'           11100100 10111101   10100000

成员运算符

#in 和 not in    运算符
#用来判断一个内容在可迭代对象里是否存在
if x in word:
   print('存在')
else:
   print('不存在')
   
#格式化打印字符串
name = '张三'
age = 18
print('大家好,我的名字是%s,我今年%d岁了,我今天挣了%f元钱'%(name,age,3.14))
#基本和C语言一样
a = 255
print('%x' % a) #ff
#字符串format
#{}也可以进行占位
#{}里面什么都不写,会直接读取后面的内容,一一对应填充
x = '大家好,我是{},我今年{}岁了'.format('张三',18)
print(x)

#{数字}根据数字的顺序来进行填入,数字从0开始
y = '大家好,我是{1},我今年{0}岁了'.format(20,'jerry')
print(y)

#{变量名}
z = '大家好,我是{name},我今年{age}岁了,我来自{addr}'.format(age=18,name='jack',addr='瑞金')
print(z)

#混合使用{数字} {变量}                                 这里变量要写在数字之后
a = '大家好,我是{name},我今年{1}岁了,我来自{0}'.format('瑞金',18,name='Tom')
print(a)

#{}什么都不写   (数字)不能混合使用

d = ['zhangsan',18,'上海',180]
#b = '大家好,我是{},我今年{}岁了,我来自{},身高{}cm'.format(d[0],d[1],d[2],d[3])
b = '大家好,我是{},我今年{}岁了,我来自{},身高{}cm'.format(*d)# *d可以直接对列表进行拆分
print(b)

info={'name':'cheis','age':23,'addr':'北京','height':190}
c = '大家好,我是{name},我来自{addr},身高{height}cm,我今年{age}岁了'.format(**info)
#这里用**
print(c)

列表的基本使用

#当我们有多个数据需要按照一定顺序保存时,我们可以考虑列表
#name1 = '张三'
#name2 = '李四'
#name3 = '王五'
#name4 = 'Jack'

#使用[]来表示一个列表,列表里的每一个数据我们称之为元素
#元素之间用逗号进行分割
names = ['张三','李四','王五','Jack','张飞','关羽','刘备','曹操','孙权']
print(names)

#可以用 list(可迭代对象) 将可迭代对象转换成为一个列表
names = list(('张三','李四','王五','Tony','张飞','关羽','刘备','曹操','孙权'))
print(names)

#和字符串一样,都可以使用下标来获取元素和对元素进行切片
#同时,我们还可以使用下标来修改列表里的元素,但字符串不能修改,字符串是不可变数据类型
#列表可以修改

print(names[3])
names[3] = '诸葛亮'
print(names)

print(names[3:5])#也是左闭右开区间

#列表的操作

#列表是用来保存多个数据的,是有序可变的
#操作列表,一般都包含增加数据,删除数据,修改数据以及查询数据
#增删改查

heros = ['刘备','张飞','关羽','曹操','孙权','诸葛亮']

#添加元素的方法   append insert extend
heros.append('孙策')
print(heros)#append 在列表的最后面追加一个数据

#insert(index,object)   需要两个参数 index表示下标   object表示对象,具体插入到哪个数据前面
heros.insert(4,'大乔')
print(heros)

x = ['周瑜','黄盖','司马懿']
#exitend(interanle)需要一个可迭代对象
#A.entend(B) ==> 将可迭代对象B添加到A里

heros.extend(x)

print(heros)
print(x)

#列表的删除
heros = ['刘备','张飞','关羽','曹操','孙权','诸葛亮','Jerry']
#pop remove clear
x = heros.pop()#pop默认删除列表最后一个数据,并且返回这个数据
print(x)
print(heros)
x = heros.pop(3)#pop可以删除指定位置上的数据,也可以返回被删除的这个数据
print(x)
print(heros)

#用来删除指定的元素
heros.remove('张飞')#如果数据在列表中不存在会报错
print(heros)

#clear 用来清空一个列表
heros.clear()
print(heros)

#查询列表元素
三国 = ['魏','蜀','吴']
print(三国.index('吴'))#查询元素的位置   如果元素不存在会报错
print(三国.count('吴'))#查询出现的次数

print('魏'in 三国)

#列表的修改
#使用下标可以直接修改列表里的元素
三国[1] = 'shu'
print(三国)

#列表的遍历
#遍历:将所有数据都访问一遍,遍历针对的是可迭代对象
#while遍历   for...in遍历
水浒传 = ['宋江','晁盖','吴用','林冲','公孙胜','卢俊义','呼延灼','柴进','鲁智深','武松','李逵','阮小五','阮小七','扈三娘','时迁','白胜','孙二娘']
#for in 循环的本质就是不断调用迭代器的 next 方法查找下一个数据
for k in 水浒传:
   print(k)
   
i = 0
while i <   len(水浒传):
   print(水浒传[i])
   i += 1
   
#列表的排序和反转
nums = [9,5,7,6,8,2,1,3,4,6]
#调用列表的sort方法可以直接对列表进行排序
#sort直接对原有的列表进行排序
nums.sort()
print(nums)
#反转
nums.sort(reverse = True)
print(nums)

#内置函数sorted
#内置函数sorted不会改变原有的列表数据,而是会生成一个新的有序数据
x = sorted(nums)
print(nums)
print(x)

#reverse
numes = ['zhangsan','lisi','wangwu']
names.reverse()
print(numes)

print(numes[::-1])

#可变数据类型和不可变数据类型
num1 = [100,200,300]
num2 = num1
print('前num1=%X,num2=%X'%(id(num1),id(num2)))
num1[0] = 1
print(num1)
print('后num1=%X,num2=%X'%(id(num1),id(num2)))

'''
python里的数据都是保存在内存里的
python里的数据又分为可变类型和不可变类型
不可变类型:字符串、数字、元组
可变类型:   列表、字典、集合
不可变数据类型如果修改值,内存地址会发生变化
可变数据类型如果修改值,内存地址不会发生变化

使用内置函数id可以获取到一个变量的内存地址
'''
a=12
b=a
print('前a=%X,b=%X'%(id(a),id(b)))
a=10
print('后a=%X,b=%X'%(id(a),id(b)))

#列表的复制
x = [100,200,300]
y = x   #x和y指向了同一个内存空间,会相互影响
x[0] = 1
print(y)
print(x)

#调用列表的copy方法可以直接对列表进行复制,这个列表和原有列表内容一样,但指向不同的内存空间
z = x.copy()
print(z)

print('%X %X %X' % (id(x),id(y),id(z)))

#除了使用列表自带的copy方法以外,还可以使用copy模块实现拷贝

import copy

a = copy.copy(x)#效果等价于x.copy(),都是一个浅拷贝

#深拷贝


#切片就是一个浅拷贝
names1 = ['张三','李四','王五','杰克马','汤姆','露西','莉莉']
names2 = names1[::]
names1[0] = 'jerry'
print(names2)

#删除列表里的空字符串
x = ['zhangsan','lili','yanyan','','tom','','xx','']
i = 0
while i < len(x):
   if x[i] == "":
       x.remove(x[i])
       i -= 1
   i += 1
print(x)

#列表的嵌套
num = [1,2,3,[100,200,300,500],4,5]#等价于多维数组
#一个学校有三个办公室,现在有10位老师等待工位的分配,请编写程序完成随机的分配
import random

teachers = ['A','B','C','D','E','F','G','H','I','j']
rooms = [[],[],[]]

for teacher in teachers:
   room = random.choice(rooms)#choice 从列表里随机选择一个数据
   room.append(teacher)
   
print(rooms)
#for循环带下标的遍历
for i,room in enumerate(rooms):
   print('房间%d里面一共有%d个老师,分别是:' % (i,len(room)),end=' ')
   for teacher in room:
       print(teacher,end=' ')
   print()

#列表推导式
#列表推导式作用是使用简单的一个语法创建一个列表
nums = [i for i in range(10)]
print(nums)

points = [(x,y)for x in range(5,9)for y in range(10,20)]
print(points)


#写出一段代码实现分组一2个list里面的元素,比如[1,2,3,4,……,100]变成[[1,2,3],[4,5,6],……]
m = [i for i in range(1,101)]
n = [m[j:j+3]for j in range(0,100)]
print(n)

#浅拷贝
import copy
nums = [1,2,3,4,5]
nums2 = nums.copy()#浅拷贝,两个内容一模一样,但不是同一个对象
nums3 = copy,copy(nums) #和nums.copy 的功能一至,都是浅拷贝,但这个要用copy文件,需要使用import copy

#深拷贝   只能使用copy模块实现
words = ['hello','hi',[100,200,300],'yes','ok']

#word1是word的一个浅拷贝
#浅拷贝可以认为只拷贝了一层
words1 = word.copy()
words[0] = '你好'
print(word1)

words[2][0] = 1
print(words1)
#这里列表里面嵌套的列表是指向的关系,
#浅拷贝不会复制指向的内容,而是拷贝后的数据也指向这个地址,如果修改了指向的原内容,那么浅拷贝数据也会变化


#深拷贝就是完全拷贝
words = ['hello','hi',[100,200,300],'yes','ok']
words2 = copy.deepcopy(words)

#而深拷贝会将所指向的内容也拷贝一份,所以修改原内容,深拷贝的值不变

元组的使用

#元组 ()
#元组和列表十分相似,都是用来保存多个数据
#元组和列表的区别:列表可变,元组不可变
words = ['hello','yes','good','hi']
nums =(9,4,3,1,7,6,3,7,6)

#和列表一样,也是一个有序的存储数据的容器
#可以通过下标来获取元素

print(nums[3])
#num[3] = 40 #error 元组是不可变数据类型,不能修改
print(nums.count(6))#查询元素出现了几次
print(nums.index(7))#查找元素的下标

#特殊情况:如何表示只有一个元素的元组?
ages = (18)#这种书写方式,ages是一个整数,并不是一个元组
print(type(ages))#<class 'int'>
ages = (18,)#如果元组里只有1个元素,则要在后面加,
print(type(ages))#<class 'tuple'>

#元组的列表的互换
print(tuple(words)) #tuple list set都是这样使用的
print(list(nums))

#元组也可以遍历
for i in nums:
   print(i)
   
#元组的合并
word1 = ('hello','good')
word2 = ('yes','ok')

print(word1+word2)    
#注意:这里的合并并没有修改元组,只是生成了一个新的元组

字典的使用

#字典     {}


#列表可以存储任意的数 据类型,但一般情况下,我们都存储单一数据类型
names = ['zhangsan','lisi','wangwu']
score = [100,98,99,97]

#这个列表里的每一个元素到底代表的是什么?
#列表只能存储值,但是无法对值进行描述
person = ['zhangsan',18,98,97,95,93,180,150]

'''
字典不仅可以保存值,还可以对值进行描述
使用大括号来表示一个字典,不仅有值value,还有值的key
字典里的数据都是以键值对key-value的形式保留的
key和value之间使用冒号:来连接
多个键值对之间用逗号,来分隔
'''
person = {'name':'zhangsan','age':18,'chinese':98,'math':95,'english':95,'gym':93,'hight':180,'weight':150}

#注意事项:
#字典里的key不可以重复,如果key重复了,后一个key对应的值会覆盖前一个
#字典里的value可以是任意数据类型,但key只能使用不可变数据类型,一般使用字符串
person = {
   'name':'zhangsan',
   'age':18,
   'hight':180,
   'weight':150,
   'age':20,#会替换上一个age值
   'isPass':True,#可以是布尔值
   'hobbies':['唱','跳','篮球','rap'],#也可以是一个列表
   4:'good',
  ('yes','hello'):100
   
   #['ok','no']:'hi'   key只能是不可变数据类型
}
print(person)

#字典的增删改查
person = {'name':'zhangsan','age':18}

#查找数据:     字典的数据在保存时是无序的,所以不能通过下标来获取

print(person['name'])#使用key获取对应的value
#如果查询的key不存在会直接报错

#需求:获取一个不存在的key时,不报错,如果这个key存在,使用默认值
#使用字典的get方法就能实现这个功能
#使用字典的get方法,如果key不存在,会默认返回None,而不报错
#get只会读取,不会添加数据
print(person.get('gender'))
#可以修改返回的值
print(person.get('gender','female'))#返回female
#如果key存在就不会返回指定的值
print(person.get('name','lisi'))#zhangsan

print(person)

#字典的修改和新增
person = {'name':'zhangsan','age':18,'addr':'瑞金'}
print(person['name'])

#使用key可以修改对应的value
person['name'] = 'lisi'#如果key存在,则会修改key对应的value

person['gender'] = 'famale'#如果key不存在,会往字典里添加一个key-value键值对
print(person)

#字典的删除 clear   pop     popitem
person.pop('name')#把name对应的键值对删除了


print(person)


result = person.popitem()#字典是无序的,所以不知道会删掉哪个

print(result)#显示被删除的键值对

print(person)

del person['addr']
print(person)

person.clear()#清空字典
print(person)

#update使用
#列表可以用extend的方法将两个列表合并成一个列表
person1 = {'name':'zhangsan','age':18}
person2 = {'addr':'瑞金',}
person1.update(person2)
print(person1)
#字典中间不能用加法合并,合并只能用update

#字典的遍历
person = {'name':'zhangsan','age':18,'height':'180'}
#列表和元组是单一的数据,字典是键值对形式

#遍历一:for in循环
for x in person:    
   print(x)        #for in 循环获取的是key
   
   print(x, '=',person[x])

#遍历二:获取所有的key,然后遍历key,根据key获取value     #相较于一,要一更好,一更简单,方法类似
#print(person.keys())   #dict_keys(['name', 'age', 'height'])
for k in person.keys():     #也可以用类似方法获取values  
   print(k, '=',person[k])

#遍历三:列表里的元素是元组,把元组当做整体进行遍历
#print(person.items())#dict_items([('name', 'zhangsan'), ('age', 18), ('height', '180')])
for item in person.items():
   print(item)
   print(item[0],'=',item[1])

#遍历四:拆包
for k,v in person.items():
   print(k,'=',v)


#练习:查询列表里是元素出现了几次
chars = ['a','c','x','d','p','a','p','a','c']

char_count = {}

for char in chars:
   if char not in char_count:
       char_count[char] = chars.count(char)
print(char_count)


#字典推导式
dict = {"a":100,"b":200,"c":300}
dict = {v:k for k,v in dict.items()}#v:k键值对
print(dict)

集合

#集合set

#创建一个空的集合要用set()
#集合是不重复的无序的,可以用{}或set来表示
#区别:   如果{}放的是键值对,那么他就是一个字典
#         如果{}放的是单个的值,那么他是一个集合

#如果集合里有重复的数据,会自动去除

names = {'zhangsan','lisi','jack','tony','jack','lisi'}
print(names)

#增加
names.add('wangwu')
print(names)
#删除
#names.clear()#清空集合
#print(names) #空集合用set()表示

names.pop()#随机删除一个
print(names)

names.remove('jack')#删除指定的元素,没有改该元素会报错
print(names)

#合并多个集合,生成一个新的集合
print(names.union({'0528','1201'}))

#A.update(B)将B拼接到A里
names.update({'zhang_day','tang_day'})
print(names)

#in可以用来查询是否在集合内
print('jack'in names)

#集合无法查询,只能用in查看是否在集合里


#集合的高级使用

#set不支持加法,但可以用减法,得到不重复的           A-B        
#求相同的可以用&                                 A&B         交
#求并集                                         A|B         并
#     求Cu(A&B)                               A^B


#转换相关的方法       list tuple   set
nums = [9,8,4,3,2,1]
x = tuple(nums)     #使用tuple内置类转换成为元组
print(x)

y = set(nums)       #使用set内置类转换成为集合
print(y)

z = list({'name':'zhangsan','age':18,'score':18})
print(z)


#python里的一个强大的内置函数,可以执行字符串里面的代码

#eval 将最外侧的引号去掉
a = 'input("请输入您的用户名")'     #a是一个字符串
b = '1+1'
print(eval(b))      


#json的使用,将列表、元组、字典等转化成json字符串
import json
#json里面只能用双引号
person = {'name':'zhangsan','age':18,'gender':'female'}
#字典如果想要把它传给前端页面或者把字典写入到一个文件里

m = json.dumps(person)#这里m是字符串
print(m)        #{"name": "zhangsan", "age": 18, "gender": "female"}
print(type(m))  #<class 'str'>

#python             json
#True               true
#False             false
#字符串             字符串
#字典               对象
#列表、元组         数组

print(json.dumps(['hello','good','yes',True]))
print(json.dumps(('hello','good','yes',False)))

n = '{"name": "lisi", "age": 19, "gender": "male"}'
s = json.loads(n)#用loads可以将json字符串转换成python里的数据
print(s)
print(type(s))

运算符

'''
+ :用来拼接,用于 字符串、元组、列表
'''
print('hello'+'world')
print(('good','yes') + ('hi','ok'))
print([1,2,3] + [4,5,6])

'''
- :只能用于集合 求差集
'''

print({1,2,3} - {3})

'''
* :可以用于 字符串、元组、列表,表示重复多次。不能用于字典和集合
'''
print('hello' * 3)
print([1,2,3] * 3)
print((1,2,3) * 3)

'''
in :成员运算符
'''
print('a' in 'abc')#字符串
print(1 in [1,2,3])#元组
print(3 in {3,4,5})#列表
print(4 in (6,4,5))#集合

#in 用于字典是用来判断key是否存在
print('zhangsan' in {'name':'zhangsan','age':18,'height':'180cm'})#False
print('name' in {'name':'zhangsan','age':18,'height':'180cm'})#True

'''
都能放在for in里面遍历
'''

'''
带下标的遍历
  enumerate 类的使用
      一般用于列表元组等有序的数据
'''
nums = [19,8,12,35,4,6,88,45,42,25]
nums = {19,8,12,35,4,6,88,45,42,25}
nums = (19,8,12,35,4,6,88,45,42,25)
for x in enumerate(nums):
   print(x)
for x,y in enumerate(nums):
   print(x,y)
   print('第%d个数据是%d' % (x,y))

函数

#函数
   
#函数的定义方法
   #在python里,用关键字 def 来声明一个函数
   
   #def 函数名(参数):
   #   函数体
   
#调用函数的方法:
   #函数名(参数)





#函数声明时,括号里的参数是形参
def tell(person1,person2):
   print(person1 +' '+  chr(23545) +' ' + person2 + ' ' +  chr(35828) ,end = ' ')
   print(chr(25105),chr(29233),chr(20320))
   
#调用的时候,括号里的参数为参
tell(chr(25105),chr(20320))          
   
#函数的返回值
def add(a,b):
   c = a + b   #这里的c是局部变量,不能跨函数
   return c    #返回c的值
   
result = add(1,2)
print(result ** 4)
 
#如果一个函数没有返回值,则会显示None  
   
   
   
   
   
   
   
   
#函数的文档说明

def add(a:int,b:int):#:int表示建议输入的类型,但输入错误类型不会报错
   '''
  注释
  '''
   return a+b
   
   
help(add)#查看函数的注释
x = add(1,2)









#函数内部修改局部变量    
#使用global 对变量进行声明,可以通过函数修改全局变量的值
word = 'hi'
def a():
   global word
   word = 'hello'
   
print(word)    
a()
print(word)

'''
globals() #查看全局变量
locals() #查看局部变量
'''
print(globals())
print(globals())



#在python里,只有函数能够分割作用域
#if 3 > 2
#   m = 'hi'#这里m是全局变量


#函数的多个返回值
def test(a,b):
   x = a // b
   y = a %  b
   return x,y          #返回的本质是一个元组
   #return [x,y]       #列表
   #return {'x':x,'y':y}#字典
   
result = test(13,5)
print('商是{},余数是{}'.format(result[0],result[1]))


#默认参数的使用
'''
在函数里定义缺省参数:
  在函数声明写形参时,给他一个默认值
  传递了参数会使用传递的实参
'''
def say_love(name1,name2,say='对'):
   print(name1 +' '+  say +' ' + name2 + ' ' +  chr(35828) ,end = ' ')
   print(chr(25105),chr(29233),chr(20320))


say_love('我','你')
say_love('我','你','想 对')#传位置参数
say_love(name1 = '我',name2 = '你',say='想 对')#传关键字参数
#如果有位置参数和关键字参数混合使用,关键字参数一定要放在位置参数后面
say_love('我',name2 = '你',say='想 对')







def add_many(number):
   x = 0
   for n in number:
       x += n
   return x

nums = []
while True:
   num = input('请输入数字,按exit退出输入:')
   if num == 'exit':
       break
   nums.append(int(num))
print(add_many(nums))





#可变参数的使用       *args表示可变位置参数   **kwargs表示可变的关键字参数
def add(a,b,*args):# *args 表示可变参数   多出来的可变参数会以元组的形式保存到args里
   c = a + b
   for arg in args:
       c += arg
   return c

print(add(1,3,5,7,9))


def add2(*args,mul=1):#缺省参数只能放在可变参数后面
   d = 0
   for arg in args:
       d += arg
   return d * mul
   
print(add2(1,3,5,7,9,mul=2))    

'''
可变数据类型和不可变数据类型传参
'''
def text(a):
   print('修改前a的内存地址0x%X' % id(a))      #调用前x的内存地址0x7FFB496CC6A0
   a = 100
   print('修改后a的内存地址0x%X' % id(a))      #修改前a的内存地址0x7FFB496CC6A0
   
def demo(nums):
   print('修改前y的内存地址0x%X' % id(nums))   #修改后a的内存地址0x7FFB496CD300
   nums[0] = 10
   print('修改后y的内存地址0x%X' % id(nums))   #调用后x的内存地址0x7FFB496CC6A0
   
x = 1
print('调用前x的内存地址0x%X' % id(x))          #调用前y的内存地址0x1331F3EB7C0
text(x)
print('调用后x的内存地址0x%X' % id(x))          #修改前y的内存地址0x1331F3EB7C0
print(x)#1

y = [3,5,6,8,2]
print('调用前y的内存地址0x%X' % id(y))          #修改后y的内存地址0x1331F3EB7C0
demo(y)
print('调用后y的内存地址0x%X' % id(y))          #调用后y的内存地址0x1331F3EB7C0
print(y)#[10, 5, 6, 8, 2]


'''
注意事项:
  函数三要素:函数名、参数、返回值
  python不允许函数重名
  如果函数重名,后一个函数会覆盖前一个函数
'''
#python里,函数名也可以理解为变量名
#定义变量名时,尽量避免内置函数和内置类

#max、sum内置函数尽量避免使用这些变量名


'''
递归函数的使用

  递归简单来说 就是函数内部调用自己
  递归最重要的就是找到出口(停止的条件)
'''

count = 0

def text():
   global count
   count += 1
   print('text')
   
   if count < 5:
       text()
   
text()

#求1到n的和
Sum = 0

def get_sum(n):
   global Sum
   Sum += n
   n = n-1
   
   if(n > 0):
       get_sum(n)      
       
get_sum(100)
print(Sum)



'''
匿名函数
  用lambda关键字能创建小型匿名函数,这种函数得名于省略了用def声明函数的标注步骤
  lambda函数的语法只包含一个语句
      lambda 参数列表:运算表达式
  匿名函数调用方式:
      1.给它定义一个名字(不常用)
      2.把这个函数当做参数传给另一个函数使用(常用)
'''

def add(a,b):
   return a+b

print("0x%X" % id(add))
add(4,5)
fn = add    #相当于给函数add起了一个别名
print("0x%X" % id(fn))
fn(4,5)


lambda a,b : a+b#匿名函数,用来表达一个简单的函数,调用的次数很少,基本上只用一次

mul = lambda a,b:a * b
print(mul(4,5))

#回调函数
def calc(a,b,fn):
   c = fn(a,b)
   return c
   
def add(x,y):
   return x+y
   
def minus(x,y):
   return x-y
   
x1 = calc(1,2,add)
x2 = calc(10,5,minus)

#使用匿名函数
x3 = calc(5,7,lambda x,y:x * y)
x4 = calc(5,7,lambda x,y:x / y)
x5 = calc(5,7,lambda x,y:x + y)
x6 = calc(5,7,lambda x,y:x - y)
print(x3,x4,x5,x6)


#sort
#有几个内置函数和内置类,用到了匿名函数
nums = [4, 8, 2, 1, 7 ,6]

sorted(nums)#sorted内置函数不会改变原有数据,而是生成一个新的列表
print(nums)

nums.sort()#列表的sort方法,会直接对列表进行排序
print(nums)


students = [
  {'name':'zhangsan','age':18,'score':98,'height':180},
  {'name':'lisi','age':21,'score':97,'height':185},
  {'name':'jack','age':22,'score':100,'height':175},
  {'name':'tony','age':23,'score':90,'height':176},
  {'name':'henry','age':20,'score':95,'height':172}
  ]
   
#字典和字典之间不能使用比较运算
#students.sort()

#缺少比较规则,需要传递参数key,指定比较规则
#key需要的是一个函数
def foo(x):
   #return x['height']
   #return x['score']
   return x['age']#通过返回值告诉sort方法,按照元素的那个属性进行排序

#在sort内部实现的时候,调用了foo,并且传入了一个参数,这个参数就是列表里的元素
students.sort(key = foo)

#也可以直接使用匿名函数
students.sort(key = lambda ele:ele['score'])
print(students)



'''
过滤
'''
#filter内置类的使用,对可迭代对象进行过滤,得到一个filter对象
#python2的时候是内置函数,python3修改成了内置类

ages = [12,23,30,17,16,22,19]
#filter可以给定两个参数,第一个参数是函数,第二个参数是可迭代对象
#filter结果是一个filter类型对象,filter对象是一个可迭代对象
x = filter(lambda ele:ele > 18,ages)
for a in x:
   print(a)
#print(list(x))



#map内置类的使用
ages = [12,23,30,17,16,22,19]
m = map(lambda ele: ele+2,ages)#让列表里的元素执行函数指定的操作
print(list(m))


#reduce
#以前是一个内置类,现在变成模块里了
#内置模块和内置类在builtins.py
from functools import reduce    #导入reduce模块

scores = [100,98,76,87]
print(reduce(lambda ele1,ele2: ele1+ele2, scores))


def bar(x,y):
   '''
  x未初始化
  x = {'name':'zhangsan','age':18,'score':98,'height':180},
  y = {'name':'lisi','age':21,'score':97,'height':185},
  '''
   '''
  x初始化为0
  x = 0
  y = {'name':'lisi','age':21,'score':97,'height':185},
  '''
   return x + y['age']
   
print(reduce(bar,students,0))#初始化的值为0
print(reduce(bar,students,10))


#简化:
print(reduce(lambda x,y:x +y['age'],students,0))



#高阶函数
'''
1.一个函数作为另一个函数的返回值
2.一个函数作为另一个函数的参数
3.函数内部再定义一个函数
'''


#一个函数作为另一个函数的返回值
def foo():
   print('我是foo,我被调用了')
   return 'foo'
   
def bar():
   print('我是bar,我被调用了')
   #return foo()
   return foo
   
x = bar()
print(x)#我是bar,我被调用了 <function foo at 0x000001895B399CA0>

x()#这里x变成了foo的别名

bar()()

y = bar()()
print(y)

#一个函数作为另一个函数的参数 lambda表达式的使用
#sort filter map reduce

#函数内部再定义一个函数
def outer():
   m = 100
   def inner():#内部函数无法在外部访问
       n = 90
       print('我是inner函数')
   print('我是outer函数')
   return inner#访问inner函数的方法


outer()
outer()()



'''
闭包的概念
  闭包 = 函数块 + 引用环境
'''
def outer(n):
   num = n
   def inner():
       return num+1
   return inner
   
print(outer(3)())#4
print(outer(5)())#6
'''
在这段程序中,函数inner是函数outer的内嵌函数,并且inner函数是outer函数的返回值。
我们注意到一个问题:
  内嵌函数inner中引用到外层函数中的局部变量num,Python解释器会这么处理这个问题呢?
  先让我们来看看这段代码的运行结果,
  当我们调用分别由不同的参数调用outer函數得到的函数时,
  得到的结果是隔离的(相互不影响),
  也就是说每次调用outer函数后 都将生成并保存一个新的局部变量num,
  这里outer函数返回的就是闭包。  
'''
#如果在一 一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,
#那么内部函数就被认为是闭包(closure).

def outer():
   x = 100
   
   def inner():
       #在函数内部修改外部函数局部变量的方法
       nonlocal x #此时,这里的x不再是新增的变量,而是外部的局部变量x
       y = x + 1
       print('inner里的y = ', y)
       x = 90  #这里不是修改外部x的值,而是在inner函数内部又创建了一个新的变量x
       print('inner里的x = ', x)
       
   print('outer里的x = {}'.format(x))
   
   return inner

outer()()



#计算代码执行的时间
   #代码运行之前获取一下时间
   #代码运行之后再获取一下时间
import time #time模块可以获取一下时间

'''
时间戳是从 1970-01-01 00:00:00 UTC 到现在的秒数
中国转化为UTC要 -8
'''
#代码运行前
start = time.time() #time模块里的time方法,可以获取当前时间的时间戳
print(start)
end = time.time()

x = 0
for i in range(1,100000000):
   x += i
   
print(x)

print(end)

print(end - start)


#优化时间计算
start = time.time() #time模块里的time方法,可以获取当前时间的时间戳
print(start)
print('hello')
time.sleep(3)
print('word')
end = time.time()
print(end - start)


def calc_time(fn):
   start = time.time()
   print(start)
   
   fn()
   
   end = time.time()
   print(end)
   
   print(end - start)

   
def demo():
   x= 0
   for i in range(1,10000000):
       x+=i
   print(x)    
   
def foo():
   print('hello')
   time.sleep(3)
   print('World')
   
calc_time(demo)
calc_time(foo)





'''
装饰器
'''
def cal_time(fn):
   def inner():
       start = time.time()
       print(start)
       
       fn()
       
       end = time.time()
       print(end)
       
       print(end - start)
   return inner

@cal_time   #先调用cal_time;然后把被装饰的函数传递给fn
def demo():
   x= 0
   for i in range(1,10000000):
       x+=i
   print(x)    
 
@cal_time  
def foo():
   print('hello')
   time.sleep(3)
   print('World')
   

demo()  #当再次调用demo函数时,此时的demo函数不再是上面的demo了,变成了函数的返回值inner       语法糖
print(demo) #<function cal_time.<locals>.inner at 0x000002DD49222670>
foo()

posted @ 2021-07-29 21:50  ୯汤୬ه٥  阅读(50)  评论(0)    收藏  举报