注册 登录
  • 欢迎访问"运维那点事",推荐使用Google浏览器访问,可以扫码关注本站的"微信公众号"。
  • 如果您觉得本站对你有帮助,那么可以扫码捐助以帮助本站更好地发展。

Python数据类型:字符串、列表、元组

Python编程 彭东稳 4082次浏览 已收录 0个评论

一、序列

在Python中,最基本的数据结构是序列(sequence)。序列中的每个元素被分配一个序号——即元素的位置,也称为索引。第一个索引是 0,第二个则是 1,以此类推。序列中的最后一个元素标记为 -1,倒数第二个元素为 -2,以次类推。

所有序列类型都可以进行某些特定的操作。这些操作包括:索引(indexing)、分片(sliceing)、加(adding)、乘(multiplying)以及检查某个元素是否属于序列的成员(成员资格)。除此之外,Python还有计算序列长度、找出最大元素和最小元素的内建函数等等。另外所有序列都支持迭代,统称为可迭代对象(iterable)。

Python包含多种内建的序列,本文主要说列表、元组和字符串。其中字符和元组属于不可变序列,不能更改,代码更安全;列表则支持插入,删除和替换等元素,是一种可变的序列。

二、通用序列操作(字符串、列表、元组)

  • 索引运算:key[index]

Python索引是从0开始的,当索引超出了范围时,Python会报一个IndexError错误。所以,要确保索引不要越界,记得最后一个元素的索引是len(classmates) – 1,如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素。切片操作对列表来说是使用非常广泛的,灵活性特别大。

  • 切片运算:key[index_start:index_end]

切片之后创建的是一个新的内存对象

  • 扩展切片运算:key[index_start:index_end:stride]

  • 相关函数(按照其在ASCII码中的顺序)

  • 成员关系判断:OBJ in NAME

三、字符串(string)

字符串是Python中最常用的数据类型之一,使用单引号或双引号来创建字符串,使用三引号创建多行字符串。字符串要么使用两个单引号,要么两个双引号,不能一单一双!Python不支持单字符类型,单字符在Python中也是作为一个字符串使用。

字符串是不可变的序列数据类型,不能直接修改字符串本身,和数字类型一样!

Python 2字符串不支持Unicode编码,其大小为8bit,要想支持Unicode编码,需使用方法u”content”。而在Python 3全面支持Unicode编码,所有的字符串都是Unicode字符串,不在需要使用u,可以自动识别,其大小为16bit。所以传统Python 2存在的编码问题不再困扰我们,可以放心大胆的使用中文。

字符常用的内置方法

str.upper():将一个字符串转变为大写。

str.lower():将一个字符串转变为小写。

str.capitalize():将一个字符串首字母转换我大写。

str.strip([chars]):返回去除两侧(不包括内部)指定字符串,默认是去除空格;另外还有rstrip和lstrip,分别是删除右边和左边指定字符。

str.index(sub[, start[, end]]):找到指定字符串首次出现的位置,[, start[, end]]表示从哪里开始和结束,可省略。

str.replace(old, new[, count]):替换一个字符或一个字符串,其中old表示修改前内容,new表示修改后内容,count表示要修改几个,可省略。

str.split(sep=None, maxsplit=-1):用来将字符串分割成序列,可以执行最大分割多少次。

配置索引运算,可以显示执行的元素:

str.startswith(suffix[, start[, end]]):判断对象中是否为执行字符首部,是则为真,否则为假。

str.endswith(suffix[, start[, end]]):判断对象中是否为执行字符结尾,是则为真,否则为假。

str.join(iterable):使用’某某’作为分隔符连接序列中的字符。

str.find(sub[, start[, end]]):可以在一个较长的字符串中查找子串,它返回子串所在位置的最左端索引,如果没有找到则返回-1。

str.translate(table):这个方法和replace方法一样,可以替换字符串中的某些部分,但是和前者不同的是,translate方法只处理单个字符。它的优势在于可以同时进行多个替换,有些时候比replace效率高的多。

str.format():格式化输出字符串。简单的说就是format里面的东西去替换前面的内容,在替换的时候,可以按某种规定来输出;format方法在Python2.6之后引入,替代了原先的%,显得更加优雅。

str.isalnum():是否全为字母或数字。

str.isalpha():是否为全字母。

str.isdigit():是否为全数字。

str.islower():是否为全小写。

str.isupper():是否为全大写。

str.isspace():是否为空格。

str.isdecimal():是否为小数。

还有很多方法,如: center()、decode()、encode()、rindex()、rsplit()等。

四、列表(list)

列表是Python中最基本也是最常用的数据结构之一。列表中的每个元素都被分配一个数字作为索引,用来表示该元素在列表内所排在的位置。第一个元素的索引是0,第二个索引是1,依此类推。

Python的列表属于容器类型,是一个有序可重复的元素集合,可嵌套、迭代、修改、分片、追加、删除,成员判断。

内置函数del()可删除元素(删除元素/删除切片/删除扩展切片)

列表常用的内置方法

L.append(object):追加元素到末尾,一次只能追加一个元素。

L.insert(index, object):指定索引位置添加元素。

L.extend(iterable):合并列表元素,跟append方法作用是不同的,可以对比一下代码。

L.count(value):查询指定元素出现的次数。

L.index(value, [start, [stop]]):查看列表中指定字符出现的索引位置。

把索引使用变量替代可以做更加方便的原处修改

L.pop([index]):根据索引从列表中剔除一个元素,不给索引默认剔除最右边的一个元素,超出索引范围会抛出异常。

L.remove(value):根据对象删除一个元素。

L.sort(key=None, reverse=False):根据元素排序,同样是在列表原处修改,支持升序降序。

L.reverse():根据元素反转,同样是在列表原处修改。

PS:Python 3针对list增加了clear、copy方法。

五、元组(tuple)

元组跟列表非常类似,属于容器类型,是任意对象的有序集合。但是tuple一旦初始化就不能修改(immutable),它属于不可变对象。

现在,classmates这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。

不可变的tuple有什么意义?因为tuple不可变,所以性能更优(指定全部元素为immutable的tuple会作为常量在编译时确定,所以速度更快),多线程安全,不需要锁,不担心被恶意修改或者不小心修改。如果可能,能用tuple代替list就尽量用tuple。

另外就是元组可哈希(字符也可哈希),列表不可哈希(字典和集合也不可哈希),什么意思呢?简单理解就是支持hash()函数的称之为可哈希,反之称之为不可哈希。

由于tuple是immutable对象,可哈希,所以可以当做dict的key;而list不可哈希,自然也不能当做dict的key。如下测试。

在Python的内置数据类型中,基本上可变的数据类型都是不可哈希的,而不可变的数据类型是可哈希的。

元组的初始化操作:

元组嵌套列表,虽然元组本身不可变,但是如果元组内嵌套了可变类型的元素,那么此类元素的修改不会返回新元素而是在原处修改。

表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的。理解了“指向不变”后,要创建一个内容也不变的tuple怎么做?那就必须保证tuple的每一个元素本身也不能变。

元组常用的内置方法

由于元组不可变,所以相对应的增删改方法都没有,只有count和index方法。

T.count(value):统计元素出现的次数。

T.index(value, [start, [stop]]):显示元素的索引位置。

六、说说不可变对象

上面我们讲了,str和tuple是不可变对象,而list是可变对象。在Python的内置数据类型中,基本上可变的数据类型都是不可哈希的,而不可变的数据类型是可哈希的。对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如:

而对于不可变对象,比如str,对str进行操作呢:

使用字符串有个replace()方法,也确实变出了’Abc’,但变量a最后仍是’abc’,这就是不可变对象,应该怎么理解呢? 我们a.replace(‘a’,’A’)结果赋值给一个变量:

要始终牢记的是,a是变量,而’abc’才是字符串对象!

当我们调用a.replace(‘a’, ‘A’)时,实际上调用方法replace是作用在字符串对象’abc’上的,而这个方法虽然名字叫replace,但却没有改变字符串’abc’的内容。相反,replace方法创建了一个新字符串’Abc’并返回,如果我们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串’abc’,但变量b却指向新字符串’Abc’了。

所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

<延伸>

Python解包(Unpacking)

Python的tuple是不是冗余设计?


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (0)or分享 (0)
关于作者:

您必须 登录 才能发表评论!