深度实践OpenStack:基于Python的OpenStack组件开发—3.3.3 字符串和列表

举报
华章计算机 发表于 2019/06/06 11:29:28 2019/06/06
【摘要】 本书摘自《深度实践OpenStack:基于Python的OpenStack组件开发》——书中第3章,3.3.3节,作者是喻涛、田亮、张家龙、赵利军、李飞。

3.3.3 字符串和列表

字符串和列表本来是不同的两种数据类型,但是它们之间有很多共性,因此这里放在一起讲。

1.字符串和列表的共性

在Python中,字符串有3种表现形式:'abc',"abc"和"""abc"""。这3种字符串都是合法的字符串,只是使用的场合不同。单引号形式的字符串和双引号的字符串基本相同,只是,在处理特殊字符的时候,双引号字符串更加方便,建议大家在平常的开发中使用双引号形式;三引号形式的字符串通常用于文档字符串和SQL语句中。

Python中没有数组的概念,与之对应的是列表。这是一种新的数据形式,一个合法的列表如下:

List_1 = [1,1.2,"abc",[1,2,3]]

可以看到,列表里面的元素可以是任意类型的数据,一个列表并不受限于元素的类型。

从本质上来说,字符串是一类特殊的列表,因此,列表的大部分操作同样适用于字符串。下面用一些示例来说明字符串(String)和列表的共同点。

取下标操作:

Str_awcloud = "awcloud"

List_awcloud = ["a","w","c","l","o","u","d"] 

print Str_awcloud[0] -> a

print List_awcloud [0] -> a

截取第1个到第4个元素之间的元素:

print Str_awcloud[1:4] -> wcl

print List_awcloud [1:4] -> ['w', 'c', 'l']

截取第1个到第4个元素之间的元素,每隔2个元素取一次:

print Str_awcloud[1:4:2] -> wl

print List_awcloud [1:4:2] -> ['w', 'l']

取得某个元素的下标:

print Str_awcloud.index("a") -> 0 

print List_awcloud.index("a") -> 0

逆序取得某个元素:

print Str_awcloud[-1] -> d 

print List_awcloud [-1] -> ['d']

追加元素:

print Str_awcloud + "678"-> awcloud678  #1

print List_awcloud + [6,7,8]-> ['a', 'w', 'c', 'l', 'o', 'u', 'd', '123', 6, 7, 8] #2

计算长度:

print len(Str_awcloud) -> 8 

print len(List_awcloud) -> 8

多次复制:

print Str_awcloud * 2 -> awcloudawcloud

print List_awcloud * 2 -> ['a', 'w', 'c', 'l', 'o', 'u', 'd', 'a', 'w', 'c', 'l', 'o', 'u', 'd]

复制:

Str_target = Str_awcloud[:] 

List_target = List_awcloud[:] 

print Str_target -> awcloud

print List_target ->-> ['a', 'w', 'c', 'l', 'o', 'u', 'd']

请注意以上加粗部分,加粗代码表示该操作将返回一个结果,该结果由另外的变量接收,并不改变当前变量。另外,请注意追加元素示例代码的#1和#2,列表没有“类型”,但是列表在进行运算时是有类型的,也就是说列表的“+”操作,必须在列表和列表之间进行。同样地,字符串的“+”操作也必须在字符串和字符串之间操作,并不支持不同类型之间的操作,这点和Java不同。

2.字符串是特殊的列表

特殊性1:字符串的值是常量,是不可变动的,而列表是可更改的。例如,

Str_awcloud = "awcloud"

List_awcloud = ["a","w","c","l","o","u","d"]

可以使用如下代码:

List_awcloud [0] = "b" -> List_awcloud 

将列表变更为[“b”,”w”,”c”,”l”,”o”,”u”,”d”]。但若使用下面的代码:

Str_awcloud[0] = "b" ->

系统会直接报错,由于此特性没有对字符串的插入、追加等操作,这些操作也不被允许,而列表则可以进行这些操作。

列表的追加:

List_awcloud.append(89) -> List_awcloud = ["b","w","c","l","o","u","d",89]

在列表的第1位插入数据:

List_awcloud[1:1] = [0,9,8] -> List_awcloud = ["b",0,9,8,"w","c","l","o","u","d",89]

特殊性2:字符串只是特殊的列表,字符串也是一种数据类型,拥有自己的特殊函数和方法。

将字符串进行大小写转换:

Str_awcloud.upper() Str_awcloud.lower() 

字符串的追加:

"".join([Str_awcloud,"123"])

说明 字符串的值是常量,是不可改变的,因此,对字符串进行追加。插入甚至修改,操作的都只是字符串的副本,并不是字符串本身。


字符串有“+”操作,也有join操作,这两个操作的执行结果是一样的,但是,从执行效率来说,join操作要比“+”快,因此,以后在对字符串进行操作时,如果遇到字符串的拼接操作,建议首选join操作,而不是“+”。

这里提出一个优化原则:编写Python代码,首要目标是可读性好,其次要求执行效率高。关于如何提高Python的执行效率,会在后面陆续介绍。

特殊性3:列表也拥有自己的特殊方法。修改一下字符串和列表之间的关系定义——字符串和列表是不同的数据类型,但是,二者之间有很多交集,很多方法可以通用,但是,并不是说字符串就是列表,字符串和列表之间没有子集关系。

关于字符串的具体操作和特性可以查看Python的帮助手册,这里不再介绍。

3.列表

首先,看一下如何构造一个列表:

List_0 = list("awcloud") 

List_1 = [1,2,3,"awcloud"]

List_2 = [x for x in range(10)] 

List_3 = [x for x in xrange(10)]

List_4 = map(lambda x: x,[1,2,3,4,5])

以上五句代码,功能是一样的,都是创建一个列表。具体分析如下。

第一句,List_0 = list(“awcloud”),实际上是调用Python的内置方法list来构造一个列表。前面已经学了数字、字符串和列表,其实,这三大类数据类型都有自己的内置构造方法,例如,int类型的构造方法是int(),字符串类型的构造方法是str(),而列表的构造方法是list()。如果需要生成或者转换成对应的数据类型,只需要调用对应的构造方法即可。

第二句,直接进行初始化。

第三句和第四句类似,里面涉及for关键字和其他的一些内置函数。

第五句直接使用其他内置函数来构造一个列表。

在以上五句代码中,引入了一些关键字,如for、in、lambda,也引入了一些内置函数,如range、xrange以及map。为了更好地理解以上代码的功能,下面将详细讲解这几个重要的关键字和函数。

关键字in:表示某个元素存在于另一个元素中。例如:

"a" in "awcloud" -> True

"a" in [1,2,3,4,5] -> False

在这个输出结果中,看到了两个新的关键字:True和False。这两个关键字用于表示真和假,与C、Java语言中的用法一样。

关键字for:用于进行迭代或者循环的关键字,与C、Java语言中的用法一样,唯一不同的是,在Python中,for关键字需要配合in关键字使用。

例如:

for x in [1,2,3] print x

关键字lambda:构造一个匿名函数,实现简易的功能。

例如:

result = lambda x:x + 1

等同于

def result(x):return x + 1

函数range:根据指定的参数返回一个列表。例如:

range(10)-> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range(10,20) -> [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

range(10,20,2) -> [10, 12, 14, 16, 18]

函数xrange:xrange的功能和range的功能类似,不同的是,range一旦执行,那么生成的列表将立即存放到内存当中,而xrange采用了一种类似懒加载的方式,当xrange被执行时并没有真正生成所需要的列表,或者说生成的列表并没有立即被放到内存当中,只有当生成的列表被调用时,该列表才会被依次展开。

因此,这里提出Python性能优化的第二条原则:在生成列表时,如果数据量比较小 (<5),建议使用range;其他情况,推荐使用xrange。

函数map:先来看一下map函数的定义。

map(function, sequence[, sequence, ...]) -> list 

可见,map接收两个参数,第一个参数为一个函数,第二个参数为一个序列或者可迭代对象,它的返回值为一个列表。

下面来看一下前面提到的列表构造的问题。

List_2 = [x for x in range(10)]

效果等同于

List_2= range(10)

但有不同于:

List_3 = [x for x in xrange(10)]

List_4 = map(lambda x: x,[1,2,3,4,5])

List_2表示使用range(10)中所产生的元素来构造一个列表。List_3同第一句,只是在内存处理方面不一样。List_4则是使用map函数产生一个列,请注意加粗部分,它们的效果是等同的,但是也存在不同之处。

List_2 = [x for x in range(10)]这种语法形式叫作列表推导,它和数学中的集合类似,例如,该句可以用如下的数学表达式表示:{x ∈[0,10)}。而List_2 = range(10)则是单纯的赋值操作,两者的性质不一样。在Python的实现中,列表推导要比直接赋值来得快。

因此,在这里提出Python性能优化的第三条原则:构造列表时,推荐使用列表推导。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。