数据类型
2021-7-1
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

 
Python主要有8种数据类型:Number(数字)、Boolean(布尔值)、None(空值)、String(字符串)、List(列表)、Tuple(元组)、Set(集合)、Dictionary(字典)
 
 
 

Number(数字)

整数

Python可以处理任意大小的整数(包括负整数),在程序中的表示方法和数学上的写法一模一样,例如:1100-80800,等等。
有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff000xa5b4c3d2
对于很大的数,例如10000000000,很难数清0的个数。Python允许在数字中间以_分隔,因此写成10_000_000_00010000000000是完全一样的,十六进制数也可以写成0xa1b2_c3d4
 
注意:Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648~2147483647
 

浮点数

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如是完全相等的。
浮点数可以用数学写法,如1.233.14-9.01。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代, 就是1.23e9,或者12.3e80.000012可以写成1.2e-5
注:Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)
 
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的,而浮点数运算则可能会有四舍五入的误差。
整数的除法为什么也是精确的?在Python中,有两种除法:
  • 一种除法是/
    • 10/3=3.3333333333333335 /除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:9/3=3.0
  • 一种除法是//(地板除):
    • 两个整数的除法仍然是整数:10//3=3
      整数的地板除//永远是整数,即使除不尽。要做精确的除法,使用/就可以。因为//除法只取结果的整数部分,所以Python还提供一个余数运算,可以得到两个整数相除的余数10%3=1
无论整数做//除法还是取余数,结果永远是整数
 

布尔值

一个布尔值只有TrueFalse两种值。在Python中,可以直接用TrueFalse表示布尔值(注意大小写),也可以通过布尔运算计算出来:
 
布尔值可以用andornot运算:
  • and:与运算,只有所有都为True,结果才是True
  • or:或运算,只要其中有一个为True,结果就是True
  • not:非运算,是一个单目运算符,把True变成FalseFalse变成True
 

空值

None是一个特殊的常量,表示空值,其和False0以及空字符串不同,它是一个特殊Python对象, None的类型是NoneType
 

字符串

字符串是以单引号'或双引号"括起来的任意文本,比如'abc'"xyz"
''""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有abc这3个字符。如果'本身也是一个字符,那就可以用""括起来,比如"I'm OK"包含的字符是I'm,空格,OK这6个字符。
 
如果字符串内部既包含'又包含",可以用转义字符\来标识。转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\
 
Python允许用r''表示''内部的字符串默认不转义:
 
如果字符串内部有很多换行,用\n写在一行里不好阅读,可以用'''...'''的格式表示多行内容
 

list

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。

创建列表

  • 使用 [ ] 创建列表
    • 创建一个列表,只需要把逗号分隔的不同数据项使用方括号[]括起来即可:
  • 使用 list() 函数创建(转换为)列表
    • 可以使用list()函数将字符串、元组、字典和集合等其他类似对象转换为列表:
 
list里面的元素的数据类型也可以不同,比如:L = ['Apple', 123, True]
嵌套列表:list元素也可以是另一个list
 
如果一个list中一个元素也没有,就是一个空的list,长度为0
 

访问列表

下标索引访问:分为两大类,即正向索引反向索引,格式为 list_name[i],其中,list_name表示列表名,i表示索引值,i可以是正数(正向索引)也可以是负数(反向索引)。
 
切片访问:使用切片访问列表的格式为 list_name[strat:end:step],其中,start表示起始索引,end表示结束索引,step表示步长。
[start:end] 是左闭右开区间。
 
for循环遍历列表:
 
检查项目是否存在:使用in关键字
 
更改列表值
 
列表连接(合并)/复制:
+连接(合并)
*复制
 

内置方法

方法
描述
append(obj)
在列表末尾添加新的对象
insert(index, obj)
在指定位置添加元素
extend(seq)
将列表元素(或任何可迭代的元素)添加到当前列表的末尾
count(obj)
统计某个元素在列表中出现的次数
index(obj)
返回具有指定值的第一个元素的索引
sort( key=None, reverse=False)
对原列表进行排序
copy()
复制列表
reverse()
颠倒列表的顺序
pop([-1])
移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
remove(obj)
移除列表中某个值的第一个匹配项
clear()
清空列表
 
Python中remove,del以及pop之间的区别
remove,del以及pop都可以用于删除列表、字符串等里面的元素,但是具体用法并不相同。
  1. remove是剔除第一个匹配的值。
  1. del是通过索引来删除当中的元素。
  1. pop是通过索引来删除当中的元素,并且返回该元素;若括号内不添加索引值,则默认删除最后一个元素。
 
 
 

tuple

另一种有序列表叫元组:tuple
tuplelist非常类似,但是tuple一旦初始化就不能修改,比如同样是列出同学的名字:
现在,classmates这个tuple不能变了,它也没有append()insert()这样的方法。其他获取元素的方法和list是一样的,可以正常地使用classmates[0]classmates[-1],但不能赋值成另外的元素。
不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple
 
tuple的陷阱:定义一个tuple时,元素就必须被确定下来
 
要定义一个只有1个元素的tuple,如果这么定义:
定义的不是tuple,是1这个数!
这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定这种情况下,按小括号进行计算,计算结果自然是1
所以,只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:
互换变量有不用创建临时变量的方法
在Python中,当我们想要互换两个变量的值或将列表中的两个值交换时,可以使用如下的格式进行,不需要创建临时变量:
这么做的原理是什么呢?
首先一般情况下Python是从左到右解析一个语句的,但在赋值操作的时候,因为是右值具有更高的计算优先级,所以需要从右向左解析。对于上面的代码,它的执行顺序如下:
先计算右值 (这里是简单的原值,但可能会有表达式或者函数调用的计算过程), 在内存中创建tuple,存储分别对应的值;计算左边的标识符,元组被分别分配给左值,通过解包(unpacking),元组中第一个标示符对应的值 ,分配给左边第一个标示符,元组中第二个标示符对应的值,分配给左边第二个标示符,完成了的值交换。
 
 

“可变的”tuple

这个tuple定义的时候有3个元素,分别是'a''b'和一个list。不是说tuple一旦定义后就不可变了吗?怎么后来又变了?
先看看定义的时候tuple包含的3个元素:
notion image
当把list的元素'A''B'修改为'X''Y'后,tuple变为:
notion image
表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说:tuple的每个元素,指向永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
怎么创建一个内容也不变的tuple?那就必须保证tuple的每一个元素本身也不能变
 
 
Python中列表和元组的区别
  • 列表是可变的,在创建之后可以对其进行任意的修改。
  • 元组是不可变的,元组一旦创建,便不能对其进行更改,可以元组当作一个只读版本的列表。
  • 元组无法复制。
  • Python将低开销的较大的块分配给元组,因为它们是不可变的。对于列表则分配小内存块。与列表相比,元组的内存更小。当你拥有大量元素时,元组比列表快。
 
 
 

dict

Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。假设要根据同学的名字查找对应的成绩,如果用list实现,需要两个list
给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,list越长,耗时越长
 
如果用dict实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢:
 
为什么dict查找速度这么快?
因为dict的实现原理和查字典是一样的,假设字典包含了1万个汉字,要查某一个字:
  • 一个办法是把字典从第一页往后翻,直到找到想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。
  • 第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。
dict就是第二种实现方式,给定一个名字,比如'Michael'dict在内部就可以直接计算出Michael对应的存放成绩的“页码”,也就是95这个数字存放的内存地址,直接取出来,所以速度非常快。
 
这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样取的时候才能根据key直接拿到value。
把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
务必注意dict内部存放的顺序和key放入的顺序是没有关系的。
 
list比较,dict有以下几个特点:
  1. 查找和插入的速度极快,不会随着key的增加而变慢
  1. 需要占用大量的内存,内存浪费多
list相反:
  1. 查找和插入的时间随着元素的增加而增加
  1. 占用空间小,浪费内存很少
所以,dict是用空间来换取时间的一种方法。
 
dict可以用在需要高速查找的很多地方,需要牢记的第一条就是dictkey必须是不可变对象
因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,可以放心地作为key。而list是可变的,就不能作为key
 
Python中dict(字典)的底层结构
Python的dict(字典)为了支持快速查找使用了哈希表作为底层结构,哈希表平均查找时间复杂度为O(1)。CPython 解释器使用二次探查解决哈希冲突问题。
 

set

setdict类似,也是一组key的集合,但不存储value。由于key不能重复,所以在set中,没有重复的key
要创建一个set,需要提供一个list作为输入集合:
注意,传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的
 
重复元素在set中自动被过滤:
 
setdict的唯一区别仅在于没有存储对应的value,但是set的原理和dict一样,所以同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。
 
 

不可变对象

可变对象与不可变对象的区别在于对象本身是否可变
  • 可变对象:list(列表) dict(字典) set(集合)
  • 不可变对象:tuple(元组) string(字符串) int(整型) float(浮点型) bool(布尔型)
 
a是变量,'abc'才是字符串对象!对象a的内容是'abc',其实是指a本身是一个变量,它指向的对象的内容才是'abc'
notion image
当调用a.replace('a', 'A')时,实际上调用方法replace是作用在字符串对象'abc'上的,而这个方法虽然名字叫replace,但却没有改变字符串'abc'的内容。相反,replace方法创建了一个新字符串'Abc'并返回,如果用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串'abc',但变量b却指向新字符串'Abc'了:
notion image
所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
  • Python
  • 变量与常量编码和字符串操作
    目录