基本引用类型:
空引用:
None 不可变
数字:
bool 不可变
int 不可变
flout 不可变
complex 不可变
序列:
str字符串 有序 不可变 可重复
tupel元组 有序 不可变 可重复
list列表 有序 可变 可重复
散列:
dict字典 无序 可变 不可重复(指key) {1:1, 2:2, 3: 3}
set集合 无序 可变 不可重复 {1:?, 2:?, 3: ?}
基本数据类型:变量中直接存储目标数据,操作变量即直接操作目标数据
引用数据类型:变量中存储指向目标数据的地址,操作变量即简介操作目标数据
Python中一切皆对象,一切皆为引用数据类型,内置六大类引用类型,数字类型、字符串类型、元组类型、列表类型、字典类型、集合类型
不可变数据类型:不可原地修改,修改变量指向的目标数据时,必须重新申请内存以存储修改后值的数据类型。Number(数字)、String(字符串)、Tuple(元组)为不可变数据类型。
可变数据类型:可以原地修改,修改变量指向的目标数据时,可以在原地存储修改后值的数据类型。可变数据类型即可变数据类型修改时内存地址不发生变化。包括List(列表)、Dictionary(字典)、Set(集合)为可变数据类型。
# 不可变类型不可原地修改
a = 1 # a指向目标数据1的内存
id(a) # a指向的地址为140720495850280
b = a + 1 # b指向a+1的结果的内存
print(b) # 2为b指向的目标数据
id(a) # 140720495850280 a+1并未改变a指向的内存地址
id(b) # 140720495850312 b指向新开辟的存储a+1结果的内存地址,若非如此id(a)应当与id(b相等)
# 可变类型可以原地修改
a = [1] # a指向[1]的内存
id(a) # 2955498803968
a[0] = 2 # 修改a中第一个元素的值
print(a) # [2]
id(a) # 2955498803968
# 可变类型可以不原地修改
a = [1]
id(a) # 2955498788416
a = a + [1]
print(a) # [1, 1]
id(a) ## 2955498806720
不可变类型
#
print(type(999)) # 十进制整型
print(type(0b1010)) # 二进制整型
Python中整型取值范围无限制
#
print(type(3.1415926)) # 浮点数
print(type(3.1415926e2)) # 科学计数法浮点数
浮点数取值范围约±10^308
# 计算机中无法精确表示所有浮点数,这是由浮点数存储方案决定的系统误差,要以有限空间尽可能存储无限的浮点数是要做取舍的
a = 0.1
b = 0.2
print(a + b)
# 0.30000000000000004
#
print(type(True)) #
print(type(False)) #
print(True == 1) # True
print(True == 2) # False
print(False == 0) # True
print(False == 2) # False
#
print(type(3-3j))
print(type(complex(3,-3)))
z = 1 + 3j
z.real
z.imag
不可变类型,字符串是若干字符的有序序列。
注:Python3字符集默认使用Unicode,编码方式默认使用UTF-8。Python2字符集默认使用ASCII,编码方式采用ASCII简易映射,Python2版本常在文件首行附加# -\*- coding: UTF-8 -\*-
注释用以显式指定编码方式,Python3版本代码无需指定。
Python中单引号和双引号的等价的。
单行字符串:单引号对、双引号对
'xxxxx'
"xxxxx"
多行字符串:三单引号对、三双引号对
"""
xxxxx
xxxxx
"""
'''
xxxxx
xxxxx
'''
字符串操作符 | 含义 |
---|---|
+ | 字符串连接符 |
* | 字符串复制符 |
in | 子串判断符 |
string[x] | 获取第x-1个字符 |
string[S:E:L] | 从[S, E)按照L的步长切片,L可为附属 |
# 步长超过字符串总长度会返回S位置上的字符
a = "0123456789"
a[::100]
# '0'
# 字符串可以使用r不进行转义,保留原始字符串
字符串操作函数 | 含义 |
---|---|
len(x) | 返回字符串x的长度 |
str(x) | 返回任意类型x对应的字符串形式,str(1.23)结果为"1.23",str([1,2])结果为"[1,2]" |
eval(expression) | eval() 函数用来执行一个字符串表达式,并返回表达式的值。eval(‘print(‘hello’)’),结果为hello |
hex(x) | 返回整数x的十六进制小写形式字符串 |
oct(x) | 返回整数x的八进制小写形式字符串 |
字符串处理方法 | 含义 |
---|---|
string.lower() | 返回字符串副本,全部字符小写 |
string.upper() | 返回字符串副本,全部字符大写 |
string.split(sep=None) | 返回一个列表,由string根据被分隔的部分组成,“A,B,C"split(”,")结果为[‘A’,‘B’,‘C’] |
string.count(sub) | 返回字串在string中出现的次数,“aaa”.count(“aa”)结果为1 |
string.replace(o;d,new) | 返回字符串副本,所有old字串被替换为new |
string.center(width[,fillchar]) | 字符串根据宽度width居中,filler可缺省 |
string.strip(chars) | 在string左侧和右侧去掉chars中列出的字符,逐一去除直至非chars所列字符 |
string.join(iter) | 在字符串中相邻两个字符之间增加字符串string |
Format Specification Mini-Language
https://docs.python.org/3/library/string.html#format-string-syntax
# f-str
print(f'予早个人blog,技术碎碎念,主要语言为{None}、{{1, 2, 3}}、{"{Go}"},包含前端、后端、AI、算法、测试、运维等内容')
# format-str
# format-str会将对象按照一定规则转为字符串并填充到模板中
# {field_name[!conversion][:format_pecification]}
# 默认位置方式
print('予早个人blog,技术碎碎念,主要语言为{}、{}、{},包含{}、{}、{}、{}、{}、{}等内容'.format(
3.14, ["Java", 0], None, b"front_end", r"后端\n", True, {"算法": False}, ("测试",), {}
))
# 指定位置方式
print('予早个人blog,技术碎碎念,主要语言为{2}、{1}、{1},包含前端、后端、AI、算法、测试、运维等内容'.format(
'Python', 'Java', 'Go'
))
# 指定名称方式
print('予早个人blog,技术碎碎念,主要语言为{v1}、{v1}、{v3},包含前端、后端、AI、算法、测试、运维等内容'.format(
v1='Python', v2='Java', v3='Go'
))
# 默认位置方式和指定名称方式可以混用,指定位置方式只能单独使用
print('予早个人blog,技术碎碎念,主要语言为{}、{}、{v1},包含{v2}、后端、AI、算法、测试、运维等内容'.format(
'Python', 'Java', v1='Go', v2="前端"
))
# 符号设置
# 给数据加前置符号。可选为+、-、space
print('{:+}'.format(520)) # +520 正数可以加+
print('{:-}'.format(520)) # 520 正数不会加-
print('{: }'.format(520)) # 520 整数可加空格,能与负数对齐
print('{:+}'.format(-520)) # -520 复数不会加+,因为有-
print('{:-}'.format(-520)) # -520 复数不会加-,因为有-
print('{: }'.format(-520)) # -520 复数不会加空格,因为有-
print('{: ,}'.format(5200)) # 5,200
# 分组设置
print('{:,}'.format(5200)) # 5,200
print('{:_}'.format(5200)) # 5_200
# 对齐设置
print('{:6}'.format(520))
print('{:=6}'.format(520))
print('{:>6}'.format(520))
print('{:<6}'.format(520))
print('{:^6}'.format(520))
print('{:06}'.format(-520))
print('{:0=6}'.format(-520))
print('{:0>6}'.format(-520))
print('{:0<6}'.format(-520))
print('{:0^6}'.format(-520))
# print('{:06}'.format( 'Python')) # ValueError: '=' alignment not allowed in string format specifier
# print('{:0=6}'.format('Python')) # ValueError: '=' alignment not allowed in string format specifier
print('{:0^6}'.format('yz'))
print('{:0>6}'.format('yz'))
print('{:0<6}'.format('yz'))
print('{:0^6}'.format('yz'))
# 类型设置
print('{0:b} {0:#b}'.format(520)) # 二进制
print('{0:o} {0:#o}'.format(520)) # 八进制
print('{0:d} {0:#d}'.format(520)) # 十进制
print('{0:x} {0:#x} {0:#X} {0:#X}'.format(552200)) # 十六进制
print('{:c}'.format(80)) # P 80的Unicode字符
print('{:e}'.format(3.14)) # 3.140000e+00 科学计数法,精度默认为精确到小数点后6位
print('{:E}'.format(3.14)) # 3.140000E+00 科学计数法,精度默认为精确到小数点后6位
print('{:f}'.format(3.14)) # 3.140000 f将参数以定点法的形式输出(不是数用nan标示,无穷用inf标示,默认精度为6)
print('{:F}'.format(3.14)) # 3.140000 F将参数以定点法的形式输出(不是数用NAN标示,无穷用INF标示,默认精度为6)
print('{:g}'.format(3.14)) # 通用浮点类型
print('{:g}'.format(31457788)) # 通用浮点类型
print('{:%}'.format(0.89)) # 89.000000% 百分数,精度默认为精确到小数点后6位
# 精度设置
print('{:.2f}'.format(3.1415)) # 3.14,小数点后的位数为2
print('{:.2g}'.format(3.1415)) # 3.1,小数点前后总位数为2
print('{:.6s}'.format('i love you')) # i hate,总位数6
"""
字符串
"""
s = " davis JoNes_aBc "
print(s.capitalize())
print(s.upper())
print(s.lower())
print(s.swapcase())
print(s.title())
print(s.startswith("Da"))
print(s.endswith("Bc"))
print(s.count("a"))
print(s.find("a")) # 找不到返回-1
print(s.find("aB"))
print(s.replace('davis', 'DAVIS'))
print(s.index("JoNes")) # 找不到抛出异常
print(s.join(" "))
print(s.strip())
print(s.strip(" "))
print(s.rstrip(" "))
print(s.lstrip(" "))
print(s.split())
print(s.split(" "))
print(s.split("a"))
s = ”Hello World“
print(s[3])
print(s[2:6])
print(s[::])
print(s[::-1])
# 字符串索引切片
# 字符串与列表相互转换,join、split
print(' '.join(['1', '2', '3', '4', '5']))
# 字符串%格式化输出,仅有%s、%d
name = input("请输入姓名:")
age = input("请输入年龄:")
process = input("请输入学习进度:")
msg = "我是%s,今年%s岁,学习进度为%s%%" % (name, age, process) # 前面%为转义标识,即%%输出%
print(msg)
# 正则表达式
# python内置模块
# re
import re
pattern = ""
str_ = ""
result = re.search(pattern, str_)
print(result.group() if result else None)
result = re.match(pattern, str_) # 必须从头匹配
print(result.group() if result else None)
result = re.findall(pattern, str_)
print(result)
result = re.finditer(pattern, str_) # 找的内容比较多的时候
for i in result:
print(i.group() if i else None)
result = re.split(pattern, str_)
result = re.sub(pattern, 'O', str_)
print(result)
obj = re.compile(pattern)
result = obj.search(str_)
print(result)
pattern = "/\b[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,6}\b/g"
str_ = "abcd [email protected] 1234 [email protected]"
result = re.search(pattern, str_)
print("---", )
print(result.group() if result else None)
# ()表示捕获分组,() 会把每个分组里的匹配的值保存起来,python分组优先加?
不可变类型,列表是若干元素的无序序列。
<class 'tuple'>
# 定义方式
a = (1, 2, 3)
b = tuple([1, 2, 3])
# 元组字面量
a = (1, 2, 3) # 标准形式
b = (1,) # 单一元素需要加,与(1)区分,(1)与1是等价的
c = 1, 2, 3 # 可省略小括号,函数返回值即为元组类型,通常不加小括号
d = 1, # 添加,与整型1区分
"""
元组
"""
t = (1, 2, 3, 'tuple', [1, 'tuple'])
t[4][0] = 2
print(t)
可变类型
# 定义方式
a = [1,2, 3]
b = list([1, 2, 3])
# 列表字面量
a = [1, 2, 3]
b = [
"12",
"21"
"1e",
"er"
] # 实际上只有三个元素,['12', '211e', 'er']
"""
列表
"""
l = [1, 2, 3]
# 索引切片同字符串,增删改查
l.append('4')
l.pop(-1)
l.extend((1, 2, 3))
l.remove(1)
l.clear()
l[0:1] = '123457890' # 根据切片修改,有多少改多少
print(len(l))
l.sort(reverse=True)
l.reverse()
列表操作符 | 含义 |
---|---|
ls[i] = x | 替换列表ls第i位元素为x |
ls[i:j:k] = lt | 用列表lt替换ls切片后多对应的子元素列表 |
ls += lt | 更新列表ls,将列表lt中的元素增加到列表ls中 |
ls *= n | 更新列表ls,将其元素重复n次 |
列表操作函数 | 含义 |
---|---|
del ls[i] | 删除ls列表中第i元素 |
del ls[i:j:k] | 删除列表ls中第i到j以k为步长的元素 |
列表处理函数 | 含义 |
---|---|
ls.append(x) | 在列表ls最后增加一个元素x |
ls.clear() | 删除列表中所有的元素 |
ls.copy() | 生成一个新的列表,赋值ls中所有的元素 |
ls.insert(i,x) | 在列表的第i位置增加元素x |
ls.pop(i) | 将列表ls中第i位置元素返回并删除该元素 |
ls.remove(x) | 将列表ls中出现的第一个元素x删除 |
ls.reserve() | 将列表ls中的元素反转 |
可变类型,字典是若干键值对组成的整体,key不允许重复,key为任意不可变类型
a = {1: "A", "c": None, (1, 2): [0]}
b = dict([(1, 2), [2, 3], {3,4}]) # 容器相对自由
"""
字典
"""
d = {'1': 1, '2': 2, '3': 3}
a = [1]
d = {a: 12}
a = 2
print(d)
# 字典的key需要是基本数据类型?
# 增
d[2] = 2
# 删
d.keys()
d.values()
d.copy()
d.clear()
d.get(1, 'NULL')
k, v = d.items()
d.setdefault(1, 12) # 有键值对不更改,无则使用值更改
d.pop(100, '123')
d.popitem() # 随机删除
d2 = {1: 2, 4: 4}
d.update(d2) # 字典更新
a, b = 1, 2
b, a = a, b
# builtins
字典合并
d1 = {"A": 1, "B": 2, "C": 3}
d2 = {"B": 4, "C": 5, "D": 6}
print({**d1, **d2})
d = {'hash': 'bang', 'slash': 'dot'}
d = dict(hash='bang', slash='dot')
d = dict({'hash': 'bang', 'slash': 'dot'})
d = dict([['hash', 'bang'], ['slash', 'dot']])
直接赋值的x
from timeit import timeit
timeit("a = {'a': 1, 'b': 2}")
0.424...
timeit("a = dict(a = 1, b = 2)")
0.889...
注:
字典类型操作符 | 含义 |
---|---|
k in d | 返回boolean,判断k键是否在字典d中 |
d[k] | 获取k对应的v,若没有对应的k则报错 |
d[k] = v | 将k对应的值修改为v,没有k就创建键值对 |
字典类型操作函数 | 含义 |
---|---|
del d[k] | 删除字典d中键k对应的键值对 |
len(k) | 返回字典中元素的个数 |
字典类型处理方法 | 含义 |
---|---|
d.keys() | 返回字典d中所有键的信息 |
d.values() | 返回字典d中所有值的信息 |
d.items() | 返回字典d中所有键值对的信息 |
dict.get(key[, value]) | 若键k存在,返回相应值,反之返回值 |
d.pop(k[, value]) | 若键k存在,返回并删除相应值,反之返回值 |
d.popitem() | 随机从字典d中以元组形式返回并删除一个键值对 |
d.clear() | 删除字典d中所有键值对 |
d.setdefault(k, default=None) | 若字典中没有k,则为k设置默认值 |
可变类型,集合是若干无序唯一元素组成的整体。
a = {1, 2, 3} # 集合没有空集合字面量,不同于()、[]、{}
b = set([1, 2, 3])
"""
集合
"""
s = {1, 2, 3}
# frozenset
集合操作符 | 含义 |
---|---|
S | T | 并,返回一个集合,包含S、T所有元素 |
S - T | 差,返回一个集合,包含在S但不在T中的元素 |
S & T | 交,返回一个集合,包含S、T都有的元素 |
S ^ T | 返回一个集合,包含S、T中互不相同的元素 |
S <=T 或 S返回boolean,判断S和T的子集关系 |
|
S>=T 或 S>T | 返回boolean,判断S和T的包含关系 |
S |= T | 更新集合S,包括在集合S和T中的所有元素 |
S -= T | 更新集合S,包括在集合S但不在T中的元素 |
S &= T | 更新集合S,包括同时在集合S和T中的元素 |
S ^= T | 更新集合S,包括集合S和T中非相同的元素 |
集合操作函数 | 含义 |
---|---|
len(s) | 返回集合s的元素个数 |
x in s | 返回boolean,判断x是否在集合s中 |
x not in s | 返回boolean,判断x是否不在集合s中 |
set(x) | 将其他变量x转换为集合类型 |
集合处理方法 | 含义 |
---|---|
s.add(x) | 若x不在集合中,将x增加到s |
s.discard(x) | 移除s中的元素x,若x不在集合s中,不报错 |
s.remove(x) | 移除s中的元素x,若x不在集合s中,产生KeyError异常 |
s.clear() | 移除s中所有元素 |
s.pop() | 随机返回s的一个元素并更新s,若s为空,产生KeyError异常 |
s.copy | 返回集合的一个副本 |
函数 | 含义 |
---|---|
abs(x) | x的绝对值 |
divmod(x,y) | 商余,(x//y,x%y),同时输出商数和余数 |
pow(x,y[,z]) | 幂余,(x**y)%z,参数z可缺省 |
round(x[,d]) | 四舍五入,d是保留小数位数,默认值为0 |
max(x1,x2,x3,…,xn) | 最大值,n不限 |
min(x1,x2,x3,…,xn) | 最小值,n不限 |
int(x) | 将x变为整数,舍弃小数部分,非四舍五入,int(123.5)==123,int(“123.5”)==123 |
float(x) | 将x变为浮点数,增加小数部分,int(123)==123.0,int(“123”)==123.0 |
complex(x) | 将x变为复数,增加虚数部分 |
字符串、元组、列表均是序列。
正向递增序号、反向递增序号
# 数据类型转换
# str -> bool
# 非空字符串为真,空字符串为假
from collections import Counter #引入Counter
a = [29,36,57,12,79,43,23,56,28,11,14,15,16,37,24,35,17,24,33,15,39,46,52,13]
b = dict(Counter(a))
print ([key for key,value in b.items()if value > 1]) # 只展示重复元素
print ({key:value for key,value in b.items()if value > 1}) # 展现重复元素和重复次数
import collections
d1 = collections.OrderedDict() # 将普通字典转换为有序字典
d1['a'] = 1
d1['b'] = 2
d1['d'] = 4
d1['c'] = 3
for k, v in d1.items():
print(k, v)
d1 = {'a': '1', 'b': '2', 'd': '4', 'c': '3'}
d1 = collections.OrderedDict(d1)
for k, v in d1.items():
print(k, v)
# 3.7及以后版本dict插入顺序和存储顺序一致
Python类型提示有type annotation和type comment两种方式,类型提示与linter协同工作,实际类型与类型提示不一致不影响运行时
:
语句将信息附加到变量或函数参数中,->
运算符用于将信息附加到函数/方法的返回值中
import math
def circumference(radius: float) -> float:
return 2 * math.pi * radius
print(circumference.__annotations__)
def test(request_data: Any):
pass
from typing import Union
from typing import Optional
def f(l1: Optional[int] = None, l2: Union[int, str, None] = None):
"""
Optional是Union的特例
:param l1:
:param l2:
:return:
"""
print(l1, l2)
注:
from __future__ import annotations
避免类型构造# headlines.py
def headline(
text, # type: str
width=80, # type: int
fill_char="-", # type: str
): # type: (...) -> str
return f" {text.title()} ".center(width, fill_char)
print(headline("type comments work", width=40))
鸭子类型,不通过其本身类型判断类型,而是通过其属性、表现判断。狗拿耗子,狗即为猫。