第三章:python 规范、变量 与 数据类型
初始 Python
PEP8 规范
-
缩进
每级缩进用4个空格,pycharm中可以设置 tab 为默认 4 个空格 -
最大行宽
限制所有行的最大行宽为79字符。超出该长度可以使用 ‘\’ 续行 -
空行
两行空行分割顶层函数和类的定义,类的方法中定义用单个空行分割。 -
编码
默认使用 utf-8 格式 -
导入库
# 正确方式 import os import sys from subprocess import Popen, PIPE # 错误方式 import os,sys
-
空格
-
括号里边避免空格
# 括号里边避免空格 # 正确写法 spam(ham[1], {eggs: 2}) # 错误写法 spam( ham[ 1 ], { eggs: 2 } )
-
逗号,冒号,分号之前避免空格
# 逗号,冒号,分号之前避免空格 # 正确写法 if x == 4: print x, y; x, y = y, x # 错误写法 if x == 4 : print x , y ; x , y = y , x
-
-
注释
与代码自相矛盾的注释比没注释更差。修改代码时要优先更新注释!
变量与常量
变量与常量就是为了让程序具备人记录事物状态的能力
1.什么是变量?
记录变化(可能会经常改变)的事物状态
eg:年龄 容貌 薪资
2.什么是常量?
记录固定(可能不经常改变)的事物状态
eg:圆周率 重力加速度
变量
变量的语法结构与底层原理
一旦看到赋值符号那么一定先看符号的右侧,在内存空间中申请一块内存空间存储数据值,给数据值绑定一个变量名,以后在进行调用就可以使用变量名来调用,减少重复代码和提高使用率。
变量名 | 赋值符号 | 数据值 |
---|---|---|
name | = | ysg |
同一个数据值可以绑定多个变量名,赋值符号也可能是变量名 如果是就先找该变量名绑定的数据值,一个变量名同一时间只能绑定一个数据值。
变量名的命名规范
- 必须由数字,字母,下划线任意组合,且不能数字开头
- 不能是python中的关键字,如:['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
- 变量具有可描述性
4. 不能是中文
变量名的命名风格
- 下划线式 python推荐使用
变量名中单词很多 彼此使用下划线隔开
name_from_mysql_db1_userinfo = 'jason' - 驼峰体式 JS推荐使用
大驼峰
NameFromMysqlDb1Userinfo = 'jason'
小驼峰
nameFromMysqlDb1Userinfo = 'jason' - 在同一个编程语言中尽量固定使用一种,不要随意切换
常量
常量:一直不变的量 ,如:圆周率 π
BIR_OF_CHINA = 1949 ,python中没有常量,约定俗成的大写为常量
除了全大写之外,其他与变量用法一致
数据类型
数据类型划分:可变数据类型,不可变数据类型
不可变数据类型:元祖、bool、int、str 可哈希
可变数据类型: list、dict、set 不可哈希
数据类型之整型int
例:
age = 18
stu_num = 56
year = 2022
# bit_length() 表示二进制有效占位数
i = 100
print(i.bit_length()) # 7
数据类型之浮点型float
例:
height = 1.83
weight = 75.5
salary = 3.1
数据类型之字符串str
大白话的意思其实就是文本类型的数据>>>: 引号引起来的部分都是字符串
应用场景:姓名 地址 爱好
代码实现:
name = 'jason'
addr = '芜湖'
hobby = '学习'
1.定义字符串有四种方式
name = 'jason'
name1 = "jason"
name2 = '''jason'''
name3 = """jason"""
2.为什么定义字符串需要有多种方式
我们在字符串中编写文本也可能会使用到引号 为了避免冲突 有了多种方式
info = "Jason老师说:'年轻不是用来挥霍的资本'"
3.如何区分三引号是字符串还是注释
关注左侧是否含有赋值符号和变量名 如果有则为字符串 没有则为注释
基本数据类型之布尔值bool
1.用来判断事物的对错 是否可行 只要用于流程控制中
2.只有两种状态
True 对的 真的 可行的
False 错的 假的 不可行的
3.python中所有数据都自带布尔值
布尔值为False的数据有: 0、None、''、[]、{}、b''、()
布尔值为True的数据有: 除了上面的都是 True
4.存储布尔值的变量名一般推荐使用is开头
is_delete = False
is_alive = True
"""
很多程序中提供的注销账户的功能 其实底层并没有删除数据 而是修改了数据的状态
id username password phone is_delete
1 jason 123 110 1
2 kevin 321 120 0
"""
数据类型之列表list
增:append insert extend
append 在末尾增加
li = ["ysg", [1, 2, 3, 4, 5], "peipei", "梦幻", "利金斯"]
li.append('阴天')
li.append("666")
li.append("[12,13,14]")
print(li)
# ['ysg', [1, 2, 3, 4, 5], 'peipei', '梦幻', '利金斯', '阴天', '666', '[12,13,14]']
insert 指定位置插入
li=["abc","efg"]
li.insert(1,"d")
print(li)
# ['abc', 'd', 'efg']
extend 迭代插人到最后
li=["abc","efg"]
li.extend("亦双弓")
print(li)
# ['abc', 'efg', '亦', '双', '弓']
li.extend([1,2,3])
print(li)
# ['abc', 'efg', '亦', '双', '弓', 1, 2, 3]
li.extend(123) # 报错:TypeError: 'int' object is not iterable
删:pop remove clear del
li = ["ysg", [1, 2, 3, 4, 5], "peipei", "梦幻", "利金斯"]
name = li.pop(1)
print(name) # 有返回值:[1, 2, 3, 4, 5],默认删除最后一个值
print(li) # ['ysg', 'peipei', '梦幻', '利金斯']
li.remove("梦幻") # 按元素删除,没有返回值
print(li) # ['ysg', 'peipei', '利金斯']
li.clear() # 清空列表
print(li) # []
li = ["ysg", [1, 2, 3, 4, 5], "peipei", "梦幻", "利金斯"]
del li[1:] # del 结合切片删除
print(li) # ['ysg']
del li # 删除列表,即删除 li 变量
print(li)
改
li = ["ysg", [1, 2, 3, 4, 5], "peipei", "梦幻", "利金斯"]
li[0] = "and"
li[1] = [1, 2, 3]
print(li) # ['ysg', [1, 2, 3], 'peipei', '梦幻', '利金斯']
# 切片 当添加的值小于切片的范围时,只添加已有的值
# 即:添加的原理是 先删除后添加
li[0:3] = "ysg"
print(li) # ['y', 's', 'g', '梦幻', '利金斯']
li[0:3] = "hw"
print(li) # ['h', 'w', '梦幻', '利金斯']
# 如果添加的值大于切片的范围时,大于的值在切片范围后继续添加
li = ["ysg", [1, 2, 3, 4, 5], "peipei", "梦幻", "利金斯"]
li[0:3] = [1, 2, 3, "abc", "efg", 'H', "123"]
print(li) # [1, 2, 3, 'abc', 'efg', '利金斯']
查
li = ["ysg", [1, 2, 3], "peipei", "黎幻镇", "利金斯"]
for i in li:
print(i)
ysg
[1, 2, 3]
peipei
黎幻镇
利金斯
排序
ss = [54, 99, 55, 76, 12, 43, 76, 88, 99, 100, 33]
l1 = [111, 222, 333, 444, 555, 666, 777, 888]
ss.sort() # 默认是升序
print(ss) # [12, 33, 43, 54, 55, 76, 76, 88, 99, 99, 100]
ss.sort(reverse=True) # 改为降序
print(ss) # [100, 99, 99, 88, 76, 76, 55, 54, 43, 33, 12]
# 颠倒列表顺序
l1.reverse() # [888, 777, 666, 555, 444, 333, 222, 111]
print(l1)
# 统计列表中某个数据值出现的次数
print(l1.count(111)) # 1
数据类型之字典dict
dic = {'age': 18, 'name': 'ysg', 'sex': 'man'}
dict key 必须是不可变数据类型,可哈希
value:任意数据类型
dict 优点:使用二分查询来搜索数据
存储了大量的关系型数据
特点:无序的
增:键值对、setdefault
dic['high'] = 180 # 没有键值对 添加
print(dic) # {'high': 180, 'name': 'ysg', 'sex': 'man', 'age': 18}
dic['age'] = 21 # 有键值对 则值覆盖
print(dic) # {'high': 180, 'name': 'ysg', 'sex': 'man', 'age': 21}
dic.setdefault("weight") # 在没有值的情况下默认为 None
print(dic) # 'high': 180, 'name': 'ysg', 'weight': None, 'sex': 'man', 'age': 21}
删:pop、clear、del
print(dic.pop('age')) # 有返回值:18,按键去删除
print(dic) # {'name': 'ysg', 'sex': 'man'}
print(dic.pop('hello',None)) # 当删除时不确定有没有该键时,可以在后面设置返回值不认会报错,返回值:None
dic.clear() # 清空字典
print(dic) # {}
del dic #删除字典
# print(dic)
改:键值对、update
dic = {'age': 18, 'name': 'ysg', 'sex': 'man',}
dic2 = {'age': 22, "weight":152}
dic['age'] = 21 # 有键值对 则值覆盖
print(dic) # {'name': 'ysg', 'age': 21, 'sex': 'man'}
dic2.update(dic) # 把 dic 追加给 dic2
print(dic) # {'name': 'ysg', 'age': 21, 'sex': 'man'}
print(dic2) # {'name': 'ysg', 'weight': 152, 'age': 21, 'sex': 'man'}
查
字典的查询方法:dic.keys、dic.valuse、dic.items、for 循环、get、键值对(在不存在改键时报错,不推荐使用)
dic = {'age': 18, 'name': 'ysg', 'sex': 'man'}
for i in dic:
print(i)
for i in dic.keys():
print(i)
for i in dic.values():
print(i)
for key, val in dic.items():
print(key, val)
v = dic['name']
print(v)
# 键值对 不推荐使用
v2 = dic['name1'] # 报错
print(v2)
# get 推荐使用
print(dic.get('name1')) # 如果没有该键 可以设置返回值
print(dic.get('name1', '不存在'))
补充说明
user_dict = {
'username': 'jason',
'password': 123,
'hobby': ['read', 'music', 'run']
}
print(dict.fromkeys(['name', 'pwd', 'hobby'], 123)) # 快速生成值相同的字典
res = dict.fromkeys(['name', 'pwd', 'hobby'], [])
print(res) # {'name': [], 'pwd': [], 'hobby': []}
res['name'].append('jason')
res['pwd'].append(123)
res['hobby'].append('study')
print('res', res) # res {'name': ['jason', 123, 'study'], 'hobby': ['jason', 123, 'study'], 'pwd': ['jason', 123, 'study']}
'''当第二个公共值是可变类型的时候 一定要注意 通过任何一个键修改都会影响所有'''
# 键存在则不修改 结果是键对应的值
res = user_dict.setdefault('username','tony')
print(user_dict, res) # {'hobby': ['read', 'music', 'run'], 'username': 'jason', 'password': 123} jason
# 存不存在则新增键值对 结果是新增的值
res = user_dict.setdefault('age',123)
print(user_dict, res) # {'age': 123, 'hobby': ['read', 'music', 'run'], 'username': 'jason', 'password': 123} 123
user_dict.popitem() # 弹出键值对 后进先出
基本数据类型之元组tuple
1.也称为'不可变'的列表
元组内索引绑定的内存地址不能修改
2.小括号括起来 内部存放多个数据值 数据值与数据值之间逗号隔开 数据值可以是任何数据类型
3.代码实现
t1 = (11, 22, 'jason')
4.元组与列表的对比
l1 = [11, 22, 33]
print(l1[0]) # 11,获取索引0对应的数据值
l1[0] = 666
print(l1) # [666, 22, 33]
t1 = (11, 22, 33)
print(t1[0]) # 11
t1[0] = 999 # 报错
print(t1)
t1 = (11, 22, [111, 222])
t1[2][1] = 666
print(t1) # (11, 22, [111, 666])
5.元组内如果只有一个数据值
t1 = (1)
t2 = (11.11)
t3 = ('jason')
print(type(t1), type(t2), type(t3)) # <class 'int'> <class 'float'> <class 'str'>
t1 = (1,)
t2 = (11.11,)
t3 = ('jason',)
print(type(t1), type(t2), type(t3)) # <class 'tuple'> <class 'tuple'> <class 'tuple'>
"""
建议:以后在使用可以存放多个数据值的数据类型时 如果里面暂时只有一个数据值 那么也建议你加上逗号
"""
元组拆包
我们把元组 (33.9425, -118.408056) 里的元素分别赋值给变量 latitude, longitude,而这所有的赋值我们只用一行声明就写完了,这就是对元组拆包的应用。
latitude, longitude = (33.9425, -118.408056)
print(latitude, longitude) # 33.9425 -118.408056
用 * 来处理剩下的元素
在 Python 中,函数用 *args 来获取不确定数量的参数算是一种经典写法了。
于是 Python 3 里,这个概念被扩展到了平行赋值中
在平行赋值中, * 前缀只能用在一个变量名前面,但是这个变量可以出现在赋值表达式的
任意位置
a, b, *rest, c = range(9)
print(a, b) # 0 1
print(rest) # [2, 3, 4, 5, 6, 7]
print(a, b, rest, c) # 0 1 [2, 3, 4, 5, 6, 7] 8
嵌套元组拆包
metro_areas = [
('Tokyo','JP',36.933,(35.689722,139.691667)), # 每个元组内有 4 个元素,其中最后一个元素是一对坐标
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))
]
print('{:15} | {:^9} | {:^9}'.format('', 'lat.', 'long.'))
fmt = '{:15} | {:9.4f} | {:9.4f}'
for name, cc, pop, (latitude, longitude) in metro_areas: # 我们把输入元组的最后一个元素拆包到由变量构成的元组里,这样就获取了坐标。
if longitude <= 0: # 即:(latitude, longitude) = (35.689722,139.691667)
print(fmt.format(name, latitude, longitude))
# 输出的内容
# | lat. | long.
# Mexico City | 19.4333 | -99.1333
# New York-Newark | 40.8086 | -74.0204
# Sao Paulo | -23.5478 | -46.6358
具名元组
collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有
名字的类——这个带名字的类对调试程序有很大帮助。
from collections import namedtuple
City = namedtuple('City', 'name country population coordinates') # 创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) # 存放在对应字段里的数据要以一串参数的形式传入到构造函数中(注意,元组的构造函数却只接受单一的可迭代对象)。
print(tokyo) # City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
print(tokyo.population) # 36.933
print(tokyo.coordinates) # (35.689722, 139.691667)
print(tokyo[1]) # JP
基本数据类型之集合set
集合:{},可变的数据类型,他里面的元素必须是不可变的数据类型,无序,不重复。(不重要)
集合的书写
定义空集合与空字典
{} 默认是字典
set() 定义空集合
增:add updata
set = {'ysg', 'pei', 'hw', 'lp', 'cp'}
set.add("女神")
print(set) # {'pei', '女神', 'hw', 'lp', 'cp', 'ysg'}
set.add("abc")
print(set) # {'abc', 'pei', '女神', 'hw', 'lp', 'cp', 'ysg'}
set.update("abc")
print(set) # {'c', 'abc', 'pei', '女神', 'a', 'b', 'hw', 'lp', 'cp', 'ysg'}
删:pop remove clear del
set = {'ysg', 'pei', 'hw', 'lp', 'cp'}
set.pop() # 随机删除
print(set.pop()) # lp
print(set)
set.remove('cp') # 按元素删除
print(set) # {'hw', 'ysg', 'lp', 'pei'}
# set.remove('cp2')
# print(set) # 报错,KeyError: 'alex2'
set.clear() # 清空列表 set()
print(set) # set()
del set # 删除字典
查:for
set = {'ysg', 'pei', 'hw', 'lp', 'cp'}
for i in set:
print(i)
# pei
# hw
# ysg
# lp
# cp
外部链接
内置方法与数据类型:https://www.processon.com/view/link/5c2d5b44e4b0fa03ce889433
作业
附加练习题
# 附加练习题(提示:一步步拆解)
# 1.想办法打印出jason
l1 = [11, 22, 'kevin', ['tony', 'jerry', [123, 456, 'jason']]]
print(l1[3][2][2]) # jason
# 2.想办法打印出大宝贝
d1 = {'name': 'jason', 'others': {'a1': 'heiheihei', 'a2': {'k1': 'hahaha', 'k2': 'hehehe', 'k3': '大宝贝'}}}
print(d1['others']['a2']['k3']) # 大宝贝
# 3.想办法打印出run
data = {'username': 'jason', 'hobby': [11, 22, {'height': 183, 'hobby': ['read', 'run', 'music']}]}
print(data['hobby'][2]['hobby'][1]) # run
获取用户输入并打印成下列格式
Name = input('请输入姓名 >>> ')
Age = input('请输入年龄 >>> ')
Sex = input('请输入性别 >>> ')
Job = input('请输入工作 >>> ')
data = '''
------------ info of Jason -----------
Name : {}
Age : {}
Sex : {}
Job : {}
---------------- end -----------------
'''.format(Name, Age, Sex, Job)
print(data)
# 打印内容
# 请输入姓名 >>> Jason
# 请输入年龄 >>> 18
# 请输入性别 >>> male
# 请输入工作 >>> Teacher
#
# ------------ info of Jason -----------
# Name : Jason
# Age : 18
# Sex : male
# Job : Teacher
# ---------------- end -----------------