《Python程序设计》——2.2 字符串

本节书摘来自华章计算机《Python程序设计》一书中的第2章,第2.2节,作者:[美]戴维 I.施奈德(David I. Schneider)著,更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.2 字符串

字符串和数值是Python处理的最为常见的数据类型。句子、短语、单词、字母、名字、电话号码、地址、社会保障号码都是典型的字符串。
2.2.1 字符串字面量
字符串字面量是字符构成的一个序列,并视其为一个整体。字符串中的字符可以是键盘上能够找到的任意字符(例如字母字面量、数字、标点符号和空格)和其他的特殊字符。
在Python程序中,字符串字面量可以表示为单引号(')或者双引号(")包围的一个字符序列。一些字符串的例子如下:

screenshot

起始和末尾的引号必须是一致的(要么是两个双引号,要么是两个单引号)。当字符串使用双引号定义时,单引号可以直接出现在字符串中,但双引号则不可以。相似地,由单引号定义的字符串可以包含双引号,但不能直接使用单引号。
2.2.2 变量
变量也可以赋值为字符串。与数值类型的变量赋值一样,字符串类型的变量首次出现在赋值语句中时即被创建出来(即变量存在)。当print函数的参数是字符串字面量或者值为字符串的变量时,只有封闭的引号中的字符(不包括引号自身)能够显示出来。
2.2.3 索引和切片
在Python中,字符串中字符所在的位置或索引可以使用数字0、1、2、3…来标识。例如,字符串的第一个字符对应索引0,第二个字符对应索引1等。如果str1是一个字符串变量或字面量,str[i]则是字符串中索引i对应的字符。图2-4展示了字符串“spam & eggs”的所有字符对应的索引。

screenshot

子字符串或切片是字符串中连续字符的一个序列。例如,以字符串“Just a moment”为例。子字符串“Jus”、“mom”、“nt”起始位置分别为0、7和11,结束位置分别为2、9和12。如果str1是一个字符串,则str1[m:n]是以位置m开始,位置n–1结束的子字符串。图2-5通过可视化帮助理解切片。设想每个字符的索引正好指向相应字符的左边。“spam & eggs”[m:n]是标记为数字m和n的箭头之间的子字符串。例如“spam & eggs”[2:6]是子字符串“am &”,也就是箭头标记2和箭头标记6之间的子字符串。
screenshot

提示:如果m≥n,也就是说,如果位置m对应的字符不在位置n对应的字符的左边,则str1[m:n]的值为空字符串(""),即不包含字符的字符串。
如果subStr是一个字符串,那么str1.find(subStr)将开始从左向右搜索字符串str1,并返回subStr首次出现的正向索引位置。而str1.rfind(subStr)将开始从右向左搜索字符串str1,并返回字符串subStr首次出现的正向索引位置。如果字符串subStr不在字符串str1中,那么find和rfind方法的返回值为–1。
例1 索引
下面的程序展示了索引的用法。
screenshot

2.2.4 反向索引
上文讨论的索引是按照字符串自左向右而确定的。Python也支持自右向左地使用负数进行索引。通过反向索引,最右端的字符索引值为-1,它左边的一个字符索引值为-2,以此类推。图2-6显示了字符串”spam & eggs”中字符的反向索引。
screenshot

例2 反向索引
下面的程序展示了反向索引。
screenshot

2.2.5 切片的默认边界
在表达式str1[m:n]中,其中一个或者两个边界都是可以忽略的。在这种情况下,左边界m的默认值为0,右边界n的默认值为字符串的长度。也就是,str[:n]包括了从字符串首字符到str1[n-1]之间的所有字符,str1[m:]包括了从str1[m]到字符串末尾的所有字符。切片str1[:]正好表示整个字符串str1。
例3 默认边界
下面的程序展示了默认边界。
screenshot

2.2.6 字符串连接
两个字符串可以连接起来组成一个新的字符串。这个操作称为连接,可以使用加号来表示。例如,“good”+“bye”为“goodbye”。由字符串、标点符号、函数和方法构成的一个可运算字符串称为字符串表达式。当一个字符串表达式出现在赋值语句或者print函数中时,字符串表达式先进行计算后再赋值或显示。
2.2.7 字符串重复
星号操作符可用来重复地连接一个字符串自身。如果str1是个字符串字面量、变量或者表达式,而n是一个正整数,那么str1 * n的值由n个str1的副本连接得到。
screenshot

2.2.8 字符串函数和方法
字符串函数操作与数值函数十分相似。它将字符串作为输入并返回相应的值。字符串方法是在字符串上进行处理的一个过程。我们已经看到过两种方法:find和rfind。这两种方法可用于定位索引。而使用方法的一般表达式形式为:
screenshot

其中括号中可以包含值。与上一节中给出的数值方法类似,字符串函数和方法可以对字符串字面量、变量和表达式进行操作。表2-3给出了str1是字符串“Python”时,一个字符串函数和六个字符串方法。其他更多的字符串方法会在后续章节中陆续介绍。
screenshot

2.2.9 链式方法
观察以下两行代码:
screenshot

这两行代码可以合并为如下的一行代码,即链式方法。
screenshot

链式方法按照从左到右的顺序依次执行。链式调用能够消除临时变量,如上例中的变量praise,因而可以生成简洁的代码。
2.2.10 input函数
input函数提示用户输入数据。一个典型的输入语句是:
screenshot

当Python执行到这个语句时,将显示“Enter the name of your city:”同时程序中止。在用户键入了他的城市名称并按下〈Enter〉(或〈return〉)键后,变量town将赋值为城市名称(如果变量先前没有创建,变量此时将立即创建)。一个input语句的一般形式为:
screenshot

其中,prompt是一个要求用户响应的字符串。
例4 解析姓名
下面的程序要求用户输入姓名后解析姓名。当程序运行时,短语“Enter a full name: ”出现后,程序执行过程中止。在用户输入单词并按下〈Enter〉(或〈return〉)键后, 将显示输出的最后两行。
screenshot

2.2.11 int、float、eval和str函数
如果str1是一个包含整数的字符串,int函数将字符串转换为整型。如果str1是一个包含任意数字的字符串,float函数将字符串转换为浮点型(float函数也可以将整型转换为浮点型)。如果str1是一个包含数值表达式的字符串,eval函数将计算相应表达式,赋值为合适的整型或浮点型。

例5 函数展示
下面的程序展示了int、float、eval函数的用法。
screenshot

一个input函数通常会返回一个字符串。然而,通过input函数与int、float或eval函数的组合,可以向程序输入数字。例如,考虑以下三个语句:
screenshot

假设用户输入一个整数25。接着,在上述每个语句执行之后,语句print(age)的输出分别为25、25.0和25。然而,如果某个用户年纪最小,他会输入数字3.5。在执行第一个input语句时,会产生一个回溯的错误消息。而执行第二个或第三个input语句后,print函数会输出3.5。eval函数在任一年龄下均输出正确的结果。
int和float函数比eval函数执行速度要快,因此Python程序员在能够安全使用的前提下更喜欢前者。在本书中,我们均会使用三个函数,但是更喜欢eval函数。
int和float函数也可以应用于数值表达式。如果x是一个整数,int(x)的值为x。如果x是一个浮点数,int函数会丢弃数字中的小数部分。float函数以此类推。eval函数不能应用于数字字面量、变量或表达式。
screenshot

str函数可以将数字转换为字符串。例如,str(5.6)的值为“5.6”,str(5.)的值为“5.0”。
字符串不可以和一个数字进行连接操作。但是,不正确的语句:
screenshot

可以用如下正确的语句来替换:
screenshot

完成两个字符串的连接。
2.2.12 内部文档
程序文档是注释的集合,用于说明程序的用途,变量的目的,程序各个部分执行的任务。要创建一个注释语句,只要以#为行首即可。当程序执行时,将完全忽视注释语句。注释有时也称为附注。在行尾加上#以及必要的信息可以用于注释一行代码。在IDLE编辑器中,按下〈Alt+3〉和〈Alt+4〉键可以注释或不注释选注的代码段。
例6 解析名字
下面重写了例4使用的文档。第一个注释说明了整个程序,第三行的注释给出了变量的含义,最后一个注释描述了它后面两行代码的目的。
screenshot

使用文档的好处包括:

  1. 帮助其他人更容易理解程序;
  2. 帮助自己之后再次阅读时更好地理解程序;
  3. 由于程序小块部分的用途可以快速确定,大的程序可以更容易阅读。
    良好的编程习惯要求程序员应该一边编写代码一边编写注释。事实上,许多软件公司在发布软件之前要求一定程度的文档,部分公司甚至通过代码的文档好坏评价程序员的水平。

2.2.13 行延续
一个长的语句可以通过在行尾(除了最后一行)使用反斜杠()分割成两个或更多行显示。例如,代码行:
screenshot

可以写成:
screenshot

Python有个特性可以用来代替反斜杠构成的行延续。任何包含在一组括号中的代码可以分散在多行。由于任何表达式都可以包含在括号里,该特性总是可以被使用。例如,上面的语句可以写成:
screenshot

行延续的这个方法对于大部分的程序员而言都是一种更好的风格,在本书中无论何时都可以使用。
2.2.14 索引和切片越界
Python不允许字符串中单个字符的索引越界,但是在切片中可以允许索引越界。例如,如果满足:
screenshot

则print(str1[7])和print(str1[-7])会触发回溯的错误消息IndexError。
如果切片的左边索引过小,切片会从字符串首开始,如果切片的右边索引过大,切片会一直到字符串尾。例如:
screenshot

注释

  1. 在本书中,我们通常使用单引号定义单个字符的字符串,而使用双引号定义其他字符串。
  2. 由于字符串表达式可以通过字面量、变量、函数、方法以及操作符的任意组合来产生字符串,单个字符串或变量也是表达式的一种特殊形式。
  3. 字符串中的每一个字符都有两个索引—一个正数和一个负数。因此,strValue[m:n]中的数字m和n可以是相反的符号。如果索引m所指字符位于索引n所指字符的左边,则切片将包括由索引所指字符开始和由索引n所指字符的左边字符之间的所有字符组成的子串。例如,"Python"[–4:5]的值为"tho"。当然,如果索引m所指字符不在索引n所指字符的左边,则切片为空字符串。
  4. 字符串中的字符是无法直接修改的。例如,以下代码试图将单词resort改为单词report,但会产生一个回溯的错误消息。
    screenshot
  5. 对于字符串,操作符+=意味着一个增量的连接赋值语句。
  6. IDLE编辑器使用绿色显示字符串,使用红色显示注释。
  7. 方法名与变量名和函数名类似,都是大小写敏感的。
  8. 为了代码的易读性,你不应该链式调用三个以上的函数。
  9. 字符串可看做具有类型str。语句print(dir(str))会显示出所有的字符串方法(但忽略其中所有以双下滑线开始和结尾的方法)。
    实践问题 2.2
  10. 假如0≤m≤n≤len(str1),那么str1[m:n]中有多少个字符?
  11. 语句“print("Computer".find('E'))?”的输出结果是什么?
    习题 2.2

在习题1~4中,给出下列代码行相应的输出。
screenshot

在习题5~46中,给出表达式的值。
screenshot
screenshot

在习题47~70中,给出下列代码行相应的输出。
screenshot
screenshot
screenshot

  1. 给出一个简单的表达式,能够丢弃字符串的最后一个字符。
  2. 给出一个简单的表达式,能够丢弃字符串的第一个字符。
  3. 由8个字符组成的字符串中,第一个字符的反向索引是什么?
  4. 由8个字符组成的字符串中,最后一个字符的正向索引是什么?
  5. 判断题:如果str1的长度为n,那么字符串str1[n-1:]会包含str1的最后一个字符。
  6. 判断题:如果str1的长度为n,那么字符串str1[n-2:] 会包含str1的最后两个字符。
  7. 判断题:str1[:n]包含str1的前n个字符。
  8. 判断题:str1[-n:]包含str1的后n个字符。
    在习题79~92中,找出其中的错误。

screenshot
screenshot

在习题93~96中,编写一行代码来完成程序的每一个步骤,显示结果数据时请使用给定的变量名。

  1. 发明家 下面的步骤给出了一个著名发明家的名字与出生年份。
    (a) 创建变量firstName,并赋值为“Thomas”。

(b) 创建变量middleName,并赋值为“Alva”。
(c) 创建变量lastName,并赋值为“Edison”。
(d) 创建变量yearOfBirth,并赋值为1847。
(e) 用逗号分隔显示发明家的全名以及出生年份。

  1. 番茄酱的价格 下面的步骤计算番茄酱的价格。
    (a) 创建变量item,并赋值为“ketchup”。

(b) 创建变量regularPrice,并赋值为1.80。
(c) 创建变量discount,并赋值为0.27。
(d) 显示短语“1.53 is the sale price of ketchup.”。

  1. 版权声明 下面的步骤展现了一个版权声明。
    (a) 创建变量publisher,并赋值为“Pearson”。

(b) 显示短语“(c) Pearson”。

  1. 建议 下面的步骤给出了一个建议。
    (a) 创建变量prefix,并赋值为“Fore”。

(b) 显示短语“Forewarned is Forearmed.”。
提示:下面的每一个习题,可能的输出结果将显示在一个阴影框中。输入语句以下划线的形式显示。

  1. 风暴的距离 如果n秒是闪电与雷声之间的间隔时间差,风暴的距离则有n/5英里远。编写一个程序,要求输入闪电与雷声之间的间隔秒数,并返回风暴的距离,结果保留小数点后两位。如图2-7所示。
  2. 训练心率 美国运动医学院建议你在有氧锻炼时维持你的训练心率。你的训练心率可以通过0.7×(220 – a) + 0.3×r来计算,其中a是你的年龄,r是你的休息心率 (当你第一次醒来后的脉搏)。编写一个程序,要求输入一个人的年龄和休息心率, 并显示他们的训练心率。如图2-8所示。
  3. 三项全能运动 骑车、跑步、游泳一小时所消耗的卡路里分别为200、475和275。一个人每消耗3 500卡路里可以减掉1磅的体重。编写一个程序,要求输入每项运动的小时数,并显示消耗掉的体重磅数。如图2-9所示。
    screenshot
  4. 电力成本 某个设备使用的电力成本可通过公式给出:
    screenshot

每千瓦时的成本因地点不同而变化。假设美国本土的消费者当前电力的平均成本为11.76美分/千瓦时。编写一个程序,允许用户计算使用一个电器的成本。图2-10计算了一个电灯持续打开一个月所需的成本。
screenshot

  1. 棒球 编写一个程序,要求输入棒球队的名字、赢得比赛的数量、输了比赛的数量,并显示球队名字和相应的胜率。如图2-11所示。
  2. 价格收益率 编写一个程序,要求输入一个公司当年的每股收益和每股价格,然后显示公司的价格收益率(即每股价格除以每股收益)。如图2-12所示。
    screenshot
  3. 车速 当汽车在干燥的水泥路面刹车制动滑行d英尺时,公式s =给出了汽车以每小时英里数的估计时速。编写一个程序,要求输入滑行距离,然后给出该车的估计时速。如图2-13所示。提示:x0.5。
  4. 百分率 编写一个程序,将一个百分比转换为一个小数。如图2-14所示。
    screenshot
  5. 速度转换 在1954年5月6日,英国运动员Sir Roger Bannister成为了第一个在4分钟内跑完一英里的人。他的平均速度是24.20千米每小时。编写一个程序,要求输入以千米每小时为单位的速度,然后显示以英里每小时为单位的速度。如图2-15所示。提示:1千米等于0.6214英里。
  6. 服务员小费 编写一个程序,输入账单的金额和小费比例,计算服务员的小费金额。如图2-16所示。
    screenshot
  7. 等价利息率 来自投资者家乡州的地方政府债券获取的利息是免税的,而在CD上的利息是收税的。因此,为了使得CD能够获得和地方政府债券一样的利息,CD必须要支付一个更高的利息率。利息率必须支付多高取决于投资者的纳税等级。编写一个程序,要求输入纳税等级和地方政府债券利率,然后显示具有相同收益的CD利息率。如图2-17所示。提示:如果纳税等级可以表示为一个小数,那么:
    screenshot
  8. 市场术语 一个商品的利润是它的售价(selling price)和进价(purchase price)的差异。另外两个市场术语是利润率=利润/进价和毛利率=利润/售价,其中两个结果表示为百分比。编写一个程序,计算一个商品的利润、利润率和毛利率。如图2-18所示。注意当售价是进价的三倍时,利润率为200%。
  9. 分析数字 编写一个程序,要求输入包含小数点的正数,然后分别显示小数点左边的数位个数和小数点右边的数位个数。如图2-19所示。
    screenshot
  10. 单词替换 编写一个程序,要求输入一个句子,以及此句中的一个单词和另外一个单词,然后显示用第二个单词替换第一个单词后的句子。如图2-20所示。
  11. 月份转换 编写一个程序,要求用户输入一个整数的月份数,然后转换为对应时间长度的年月数。如图2-21所示。程序应该使用整除和求模运算符。
  12. 长度转换 编写一个程序,要求用户输入一个整数的英寸数,然后转换为对应长度的英尺和英寸数。如图2-22所示。程序应该使用整除和求模运算符。

screenshot

实践问题2.2的解答

  1. n – m。当m = 0时,str1[0:n]中的字符数目是n。随着数字由0变到m,字符数目也将依次减去m。
  2. –1。在字符串“Computer”中没有大写的字母E。find方法是区分大小写字母的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值