Python学习:数据类型
概述
什么是数据
数据即变量的值,如name = 'John'
,John
则是我们保存的数据。
Python3 中有六个标准的数据类型:
- Number(数值)
- String(字符串)
- List(列表)
- Tuple(元组)
- Sets(集合)
- Dictionary(字典)
数值
Python的数值类型包括常规的类型:整数(没有小数部分的数字)、浮点数(通俗地说,就是有小数部分的数字)以及其它数值类型(复数、分数、有理数、无理数、集合、进制数等)。除了十进制整数,还有二进制数、八进制数、十六进制数。
需要说明的:
- Python 3.x中的整数不区分一般整数和长整型整数,3.x版本中的整数支持无穷精度;
- 任何时候浮点数都是不精确的。当带有小数点或科学计数的标记符号e或E,就表示这是浮点数;
- 当浮点数参与表达式的运算时,会以浮点数的规则进行运算,也就是整数会转换成浮点数类型;
- 数值类型是不可变对象,不可变意味着不可原处修改;
数值类型不可变说明:假如a = 3333
,那么现在内存中会有一个内存块保存数值对象3333,如果修改它,比如对它加上1操作a += 1
,python将创建一个新的内存块用来保存新的数值对象3334,而不是在3333那个内存块中直接修改为3334,所以那个原始的数值3333就被丢弃了,它会等待垃圾回收器去回收。
布尔
Python中True
表示真,False
表示假,这两个值是数值1和0的字符串表示格式:
1 | type(True) |
同时,bool类型是int类型的一个子类:
1 | bool.__bases__ |
哪些数据是False
:
- 整数值0、浮点数值0.0等、空字符串都为假;
None
为假;- 空数据对象都是假,比如
[]
、{}
、()
等;
Tips:
None
为假,它不是表示对象为空,也不是表示对象未定义。它自身就是一个实实在在的数据对象,在内存中有自己的内存地址**,而且整个python全局只有一个唯一的None
对象。可以认为,None
是一种特殊的数据对象,像数值1、字符串’a’一样,只不过内存中这个数据对象里面存储的数据是我们不得而知的,但它永远表示为False
。在Python中,没有显式定义return
语句的函数、方法并不意味着没有返回值,它们的默认返回值是None
。
字符串
字符串(String):一个有序的字符集合,用来存储和表现基于文本的信息,要求使用单引号或双引号括起来。使用双引号的一个好处,就是字符串中可以使用单引号字符。例如:
1 | "I'm a dog." a= |
字符串是“不可变的”,它不能被更改。尝试对字符串中的一个字符重新赋值,将导致TypeError
错误。例如:
1 | r"It's a cat" a= |
转义
反斜杠\
可以用来转义
1 | 'desn't' |
如果你不希望前置了\
的字符转义成特殊字符,可以使用原始字符串 方式,在引号前添加r
即可:
1 | print('C:\some\name') |
按下标取值
字符串是可以被索引(下标访问)的,第一个字符索引是0。单个字符并没有特殊的类型,只是一个长度为一的字符串。
1 | "hello world!" a= |
切片
1 | "hello world!" a= |
长度
1 | "hello world!" a= |
in和not in
1 | "hello world!" a= |
跨行连续输入
字符串字面值可以跨行连续输入。一种方式是用三重引号:"""..."""
或'''...'''
。字符串中的回车换行会自动包含到字符串中,如果不想包含,在行尾添加一个\
即可。
1 | print("""\ |
拼接
字符串可以用+
进行连接,也可以用*
进行重复。
1 | 'haha' a= |
相邻的两个或多个字符串字面值(引号引起来的字符)将会自动连接到一起。
1 | 'hi''story' |
字符串的方法
转换大小写
upper()和lower()字符串方法返回一个新字符串,其中原字符串的所有字母都被相应地转换为大写或小写。字符串中非字母字符保持不变。
1 | 'Hello world!' a = |
Tips:这些方法没有改变字符串本身, 而是返回一个新字符串。如果你希望改变原来的字符串, 就必须在该字符串上调用
upper()
或lower()
,然后将这个新字符串赋给保存原来字符串的变量,如a=a.upper()
。
判断大小写
如果字符串至少有一个字母, 并且所有字母都是大写或小写,isupper()
和islower()
方法就会相应地返回布尔值True
。否则, 该方法返回False
。
1 | 'Hello world!' a = |
isX字符串方法
除了islower()
和isupper()
, 还有几个字符串方法,它们的名字以is
开始。下面是一些常用的isX
字符串方法:
isalpha()
返回True
,如果字符串只包含字母,并且非空;isalnum()
返回True
,如果字符串只包含字母和数字,并且非空;isdecimal()
返回True
,如果字符串只包含数字字符,并且非空;isspace()
返回True
,如果字符串只包含空格、制表符和换行,并且非空;istitle()
返回True
,如果字符串仅包含以大写字母开头、后面都是小写字母的单词;
判断开始的字符串和结束的字符串
startswith()
和endswith()
方法返回True
,如果它们所调用的字符串以该方法传入的字符串开始或结束。否则,方法返回False
。
1 | "I'm a dog." a= |
字符串连接
如果有一个字符串列表,需要将它们连接起来,成为一个单独的字符串,join()
方法就很有用。join()
方法在一个字符串上调用,参数是一个字符串列表,返回一个字符串。返回的字符串由传入的列表中每个字符串连接而成。
1 | ','.join(['dog','cat','fish']) |
字符串分割
split()
方法针对一个字符串调用,返回一个字符串列表。
1 | "I'm a dog".split() |
对齐文本
rjust()
和ljust()
字符串方法返回调用它们的字符串的填充版本,通过插入空格来对齐文本。这两个方法的第一个参数是一个整数长度,用于对齐字符串。
1 | 'dog'.rjust(10) |
rjust()
和ljust()
方法的第二个可选参数将指定一个填充字符,取代空格字符。
1 | 'dog'.rjust(10,'*') |
center()
字符串方法与ljust()
与rjust()
类似,但它让文本居中,而不是左对齐或右对齐。
1 | 'dog'.center(20,'=') |
删除空白字符
strip()
字符串方法将返回一个新的字符串,它的开头或末尾都没有空白字符。lstrip()
和rstrip()
方法将相应删除左边或右边的空白字符。
1 | ' Hello World ' a = |
替换字符串
replace()
方法把字符串中的old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max
,则替换不超过max
次。
语法格式如下:
1 | str.replace(old, new[, max]) |
例如:
1 | 'ok!ok!are you ok?' text = |
字符串格式化
字符串格式化目前有三种方式,分别为占位符(%)、format
、f-string
。
f-string
在Python3.6中,引入了一种新的格式化字符串的方法:f-string
。相比占位符和format
,f-string
更加方便简单。
f-string
是指以F
或f
为前缀的字符串。例如:
1 | 30 length = |
3.8版本又引入一个=
符号,例如:
1 | f'矩形{length=}cm,{width=}cm,面积为{length*width}' |
常见问题解决方案
使用多个界定符分割字符串
问题
你需要将一个字符串分割为多个字段,但是分隔符(还有周围的空格)并不是固定的。
解决方案
string
对象的 split()
方法只适应于非常简单的字符串分割情形, 它并不允许有多个分隔符或者是分隔符周围不确定的空格。 当你需要更加灵活的切割字符串的时候,最好使用 re.split()
方法:
1 | 'asfaf dg;gdg,ddggd,hfhh;gddd gg' line = |
知识点补充:re.split()方法
语法格式:
1 | import re |
列表
参考:列表的更多特性
Python中没有数组,但是加入了更加强大的列表(list)。
从形式上看,列表会将所有元素都放在一对中括号[]
中,相邻元素之间用逗号分隔,元素可以为任何类型,如下所示:
1 | [element1,element2,element3,...,elementn] |
可以通过type
函数查看类型:
1 | type(['sss',2.34,['sds',11],'ab']) |
列表的取值
通过下标
列表通过下标来获取列表中的单个值。列表中第一个值的下标是0
,第二个值的下标是 1
,第三个值的下标是 2
,以此类推。例如:
1 | 1,2,3,4,'ddd'] a=[ |
Tips:下标只能是整数, 不能是浮点值,否则将导致
TypeError
错误。
列表也可以包含其他列表值。这些列表的列表中的值, 可以通过多重下标来访
问, 像这样:
1 | 1,2,[85,'dog'],3,4,'ddd'] a=[ |
虽然下标从0
开始并向上增长,但也可以用负整数作为下标。整数值−1
指的是
列表中的最后一个下标,−2
指的是列表中倒数第二个下标, 以此类推。
1 | 1,2,[85,'dog'],3,4,'ddd'] a=[ |
切片
就像下标可以从列表中取得单个值一样,“切片”可以从列表中取得多个值,结果是一个新列表。像下标一样, 但它有两个冒号分隔的整数,第一个数字为切片的起始位置,第二个数字为列表的长度位置,第三个数字为元素的间隔,例如:
1 | 1:5] a[ |
可以省略切片中冒号两边的一个下标或两个下标。省略第一个下标相当于使用0
,或列表的开始。省略第二个下标相当于使用列表的长度,意味着分片直至列表的末尾。例如:
1 | 3] a[: |
用len()取得列表的长度
len()
函数将返回传递给它的列表中值的个数,就像它能计算字符串中字符的个数一样。在交互式环境中输入以下代码:
1 | len(a) |
用下标改变列表中的值
可以使用列表的下标来改变下标处的值。例如:
1 | a |
列表连接和列表复制
+
操作符可以连接两个列表,得到一个新列表,就像它将两个字符串合并成一新字符串一样。*
操作符可以用于一个列表和一个整数,实现列表的复制。
1 | 1,2,3] + ['a','b','c'] [ |
用 del 语句从列表中删除值
del
语句将删除列表中下标处的值,表中被删除值后面的所有值,都将向前移动一个下标。
1 | 1, 2, 3, 'a', 'b', 'c'] a = [ |
in和not in操作符
利用in
和not in
操作符,可以确定一个值否在列表中。像其他操作符一样,in
和not in
用在表达式中,连接两个值:一个要在列表中查找的值, 以及待查找的列表。这些表达式将求值为布尔值。
1 | 'cat','dog','pig'] a = [ |
多重赋值
1 | 'cat','dog','pig'] a = [ |
但变量数和列表中元素数量不符时,会报ValueError
1 | 'cat','dog','pig','fish'] a = [ |
有时候,你可能只想解压一部分,丢弃其他的值。对于这种情况Python
并没有提供特殊的语法。 但是你可以使用任意变量名去占位,到时候丢掉这些变量就行了。
1 | 'cat','dog','pig','fish'] a = [ |
列表的方法
常用方法:增、删、改、查、排序。
查找
列表值有一个index()
方法,可以传入一个值,如果该值存在于列表中,就返回它的下标。如果该值不在列表中,Python 就报ValueError
。
1 | 'cat','dog','pig'] a = [ |
增加
方法有:list.append(x)
,list.insert(i, x)
list.append(x)
在列表的末尾添加一个元素。相当于a[len(a):] = [x]
。
1 | 'cat','dog','pig'] a = [ |
list.insert(i, x)
在给定的位置插入一个元素。第一个参数是要插入的元素的索引,所以a.insert(0, x)
插入列表头部, a.insert(len(a), x)
等同于a.append(x)
。
1 | 2,'fish') a.insert( |
删除
给remove()
方法传入一个值,它将从被调用的列表中删除。
1 | 'cat') a.remove( |
Tips:如果知道想要删除的值在列表中的下标,
del
语句就很好用。如果知道想要从列表中删除的值,remove()
方法就很好用。
排序
数值的列表或字符串的列表,能用sort()
方法排序。
1 | 'cat', 'dog', 'fish', 'pig', 'bird'] a=[ |
需要注意的是
sort()
方法当场对列表排序。不要写出a = a.sort()
这样的代码,试图记录返回值。- 不能对既有数字又有字符串值的列表排序,因为 Python不知道如何比较它们,否则会报
TypeError
错误。
1 | 'cat',1,3,'fish'] a = [ |
sort()
方法对字符串排序时,使用“ASCII字符顺序”,而不是实际的字典顺序。这意味着大写字母排在小写字母之前。因此在排序时,小写的a
在大写的Z
之后。
1 | 'dog','Big','Small','fish'] a=[ |
列表推导式
列表推导式用于使用其他列表创建一个新列表。
语法格式
如下:
1 | # 格式1 |
例子
例1
1 | # 求1-9的平方组成的列表 |
结果如下:
1 | [1, 4, 9, 16, 25, 36, 49, 64, 81] |
例2
1 | # 求1-9中偶数的平方组成的列表 |
结果如下:
1 | [4, 16, 36, 64] |
常见问题解决方案
删除序列相同元素并保持顺序
问题
怎样在一个列表上面保持元素顺序的同时消除重复的值?
解决
去重可以用not in
判断,排序可以用sort
方法。
1 | def dedupe(items): |
使用上述函数验证
1 | 1515,23,546,77,34,666,23,12,546] a = [ |
Tips:不能对既有数字又有字符串值的列表排序,因为 Python不知道如何比较它们,否则会报
TypeError
错误。
找出出现次数最多的元素
问题
怎样找出一个列表中出现次数最多的元素呢?
解决方案
collections.Counter
类就是专门为这类问题而设计的, 它甚至有一个有用的 most_common()
方法直接给了你答案。
1 | from collections import Counter |
过滤列表元素
问题
有一个纯数据的列表,想利用一些规则从中提取出需要的值或者是缩短列表长度。
解决方案
最简单的过滤序列元素的方法就是使用列表推导式。
1 | 23, 455, 23.5, 98, 21184, 4, -5, 0, 12, -111] mylist = [ |
元组
元组(Tuple)是由一系列按特定顺序排序的元素组成。
与列表(List)的区别
元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号,列表使用方括号。
格式
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。通过( )
创建元组后,一般使用=
将它赋值给某个变量,具体格式为:
1 | tuplename = (element1, element2, ..., elementn) |
从存储内容上看,元组可以存储整数、实数、字符串、列表、元组等任何类型的数据,并且在同一个元组中,元素的类型可以不同,例如:
1 | info = ('John', '16', ('hh',54)) |
元组与字符串类似,下标索引从0开始,可以进行截取,组合等。
1 | 2] info[ |
集合
集合(set)是一个无序不重复元素的序列。
基本功能是进行成员关系测试和删除重复元素。
可以使用大括号 { }
或者set()
函数创建集合.
Tips:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
例如:
1 | info = {'John', '16', 'boy'} |
增删查
查询
1 | 'good') info.add( |
copy元素
1 | info1 |
删除元素
清空元素
1 | info.clear() |
交集、并集、差集、交叉补集
1 | # 交集 |
字典
像列表一样,字典(dict)是许多值的集合。但不像列表的下标,字典的索引可以使用许多不同数据类型,不只是整数。字典的索引被称为键(key),键及其关联的值称为键-值(key-value)对。
语法格式
1 | dictname = {'key':'value1', 'key2':'value2', ..., 'keyn':valuen} |
例如
1 | myCat = {'size': 'fat', 'color': 'gray', 'disposition': 'loud'} |
将一个字典赋给myCat
变量。这个字典的键是'size'
、'color'
和'disposition'
。这些键相应的值是'fat'
、'gray'
和'loud'
。可以通过它们的键访问这些值:
1 | 'size'] myCat[ |
字典仍然可以用整数值作为键, 就像列表使用整数值作为下标一样, 但它们不必从0
开始,可以是任何数字。
1 | a = {12: 'fish', 523: 'lion'} |
字典与列表的区别
不像列表,字典中的表项是不排序的。但字典中没有“第一个”表项。虽然确定两个列表是否相同时,表项的顺序很重要,但在字典中,键-值对输入的顺序并不重要。
1 | 'dog','fish','cat'] a = [ |
因为字典是不排序的,所以不能像列表那样切片。尝试访问字典中不存在的键,将导致KeyError
出错信息。这很像列表的“越界”IndexError
出错信息。
1 | 'size': 'fat', 'color': 'gray', 'disposition': 'loud'} myCat = { |
字典的方法
字典的键、值和键-值对
字典的键、值和键-值对:keys()
、values()
和items()
。
利用keys()
、values()
和items()
方法,循环分别可以迭代键、值或键-值对。请注意,items()
方法返回的dict_items
值中,包含的是键和值的元组。
1 | 'size': 'fat', 'color': 'gray', 'disposition': 'loud'} myCat = { |
通过in
和not in
检查某个键或值是否存在于字典中。
1 | 'name' in myCat.keys() |
get()方法
字典有一个get()
方法,它有两个参数:要取得其值的键,以及如果该键不存在时,返回的备用值。
1 | a = {'cat': 2,'dog': 5,'fish': 10} |
setdefault()方法
setdefault()
方法提供了一种方式,在一行中完成这件事。传递给该方法的第一个参数,是要检查的键。第二个参数,是如果该键不存在时要设置的值。如果该键确实存在,方法就会返回键的值。
1 | a = {'cat': 2,'dog': 5,'fish': 10} |
常见问题解决方案
字典中的键映射多个值
问题
怎样实现一个键对应多个值的字典?
解决方案
如果你想要一个键映射多个值,那么你就需要将这多个值放到另外的容器中, 比如列表或者集合里面。例如:
1 | d = { |
选择使用列表还是集合取决于你的实际需求。如果你想保持元素的插入顺序就应该使用列表, 如果想去掉重复元素就使用集合(并且不关心元素的顺序问题)。
字典的运算
问题
怎样在数据字典中执行一些计算操作,比如求最小值、最大值?
以下是蔬菜价格的数据字典:
1 | vegetables = { |
找出价格最便宜的蔬菜和最贵的蔬菜。
解决方案
如果你在一个字典上执行普通的数学运算,你会发现它们仅仅作用于键,而不是值。比如:
1 | print(min(vegetables)) # Returns 'cucumber' |
使用字典的 values()
方法来解决这个问题:
1 | a = min(vegetables.values()) |
输出结果为:
1 | The lowest price for vegetables is 1.75. |
但不是最终需要得到的结果,最终需要知道最低和最高价格的蔬菜。
zip()
函数方案通过将字典”反转”为 (值,键) 元组序列来解决了上述问题。
1 | a = min(zip(vegetables.values(),vegetables.keys())) |
输出结果为:
1 | The lowest price for vegetables is (1.75, 'cucumber') |