Article Outline

# 字符串

``print(1.1 + 2.2)``
``3.3000000000000003``

## 字符码表的转换

``````a = ord('a')
b = chr(122)

print(a)
print(b)

a = ord('氅')  # 完了，汉字也有你不认识的吧？
b = chr(25354) # 这个字估计你也不认识……

print(a)
print(b)

# ord('Python') # 这一句会报错``````
``````97
'z'
27653
'挊'``````

## 字符串的标示

``'Simple is better than complex.' # 用单引号``
``'Simple is better than complex.'``
``"Simple is better than complex." # 用双引号``
``'Simple is better than complex.'``
``````# 用三个单引号。注意输出结果中的 \n
# 这个字符串，看起来是两行，保存在内存或者变量之中的时候，
# 是一整串，其中的换行是用 \n 表示的。
'''
Simple is better than complex.
Complex is better than complicated.
'''``````
``'\nSimple is better than complex.\nComplex is better than complicated.\n'``
``````#用三个双引号。注意输出结果中的 \n
"""
Simple is better than complex.
Complex is better than complicated.
"""``````
``'\nSimple is better than complex.\nComplex is better than complicated.\n'``
``````print(
"""
Simple is better than complex.
Complex is better than complicated.
"""
) #用 print() 输出的时候，\n 就是不可见字符，字符串本身如下：
# '\nSimple is better than complex.\nComplex is better than complicated.\n'
# 其中的 \n 被打印出来的时候显示成换行``````
``````Simple is better than complex.
Complex is better than complicated.``````

## 字符串与数值之间的转换

``````a = int('3')
b = float('3')
c = str(3.1415926)
# d = int('3.1415926') # 这一行会报错
print(a)
print(b)
print(c)
# print(d)``````
``````3
3.0
'3.1415926'``````

`input()` 这个内建函数的功能是接收用户的键盘输入，而后将其作为字符串返回。它可以接收一个字符串作为参数，在接收用户键盘输入之前，会把这个参数输出到屏幕，作为给用户的提示语。这个参数是可选参数，直接写 `input()`，即，没有提供参数，那么它在要求用户输入的时候，就没有提示语。

``````age = input('Please tell me your age: ')
if age < 18:
print('I can not sell you drinks...')
else:
print('Have a nice drink!')``````
``````Please tell me your age:  19

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-9-0573fe379e83> in <module>
----> 2 if age < 18:
3     print('I can not sell you drinks...')
4 else:
5     print('Have a nice drink!')

TypeError: '<' not supported between instances of 'str' and 'int'``````

``````age = int(input('''Please tell me your age:
an int number , e.g: 22
'''))
if age < 18:
print('I can not sell you drinks...')
else:
print('Have a nice drink!')``````
``````Please tell me your age:  19
Have a nice drink!``````

## 转义符

``'\\'``
``'\\'``
``'\'``
``````  File "<ipython-input-10-d44a383620ab>", line 1
'\'
^
SyntaxError: EOL while scanning string literal``````

``'He said, it's fine.'``
``````  File "<ipython-input-11-2bcf2ca6dd95>", line 1
'He said, it's fine.'
^
SyntaxError: invalid syntax``````

``````# 要么你这么写：
'He said, it\'s fine.'
# 要么你这么写：
"He said, it's fine."
# 要么，不管用单引号还是双引号标示字符串，都习惯于用 \' 和 \" 书写属于字符串内部的引号……
"He said, it\'s fine."``````
``````"He said, it's fine."
"He said, it's fine."
"He said, it's fine."``````

``````s = "He said, it\'s fine." # raw
print(s)                   # presentation``````
``He said, it's fine.``

## 字符串的操作符

``````s = 'Hey!' + ' ' + 'You!' # 使用操作符 +
print(s)``````
``'Hey! You!'``
``````s = 'Hey!' 'You!' # 空格与 + 的作用是相同的。
print(s)``````
``'Hey!You!'``

``````s = 'Ha' * 3
print(s)``````
``'HaHaHa'``
``````s = '3.14' * 3
print(s)``````
``'3.143.143.14'``

``print('o' in 'Hey, You!')``
``True``

## 字符串的索引

0 1 2 3 4 5
P y t h o n
-6 -5 -4 -3 -2 -1
``````s = 'Python'
for char in s:
print(s.index(char), char)``````
``````0 P
1 y
2 t
3 h
4 o
5 n``````

``````s = 'Python'
for i in range(len(s)):
print(s[i])

#上面的代码仅是为了演示索引操作符的使用，更简洁的写法是：
for i in s:
print(i)``````
``````P
y
t
h
o
n``````

• `s[index]` —— 返回索引值为 `index` 的那个字符
• `s[start:]` —— 返回从索引值为 `start` 开始一直到字符串末尾的所有字符
• `s[start:stop]` —— 返回从索引值为 `start` 开始一直到索引值为 `stop` 的那个字符之前的所有字符
• `s[:stop]` —— 返回从字符串开头一直到索引值为 `stop` 的那个字符之前的所有字符
• `s[start:stop:step]` —— 返回从索引值为 `start` 开始一直到索引值为 `stop` 的那个字符之前的，以 `step` 为步长提取的所有字符

``````s = 'Python'
print(s[1])
print(s[2:])
print(s[2:5])
print(s[:5])
print(s[1:5:2])``````
``````'y'
'thon'
'tho'
'Pytho'
'yh'``````

## 处理字符串的内建函数

Python 内建函数中，把字符串当做处理对象的有：`ord()``input()``int()``float()``len()``print()`。再次注意，`ord()` 只接收单个字符为参数。

``````print( ord('\n') )
print( ord('\t') )
print( ord('\r') )
print( chr(65) ) # 与 ord() 相对的函数
s = input('请照抄一遍这个数字 3.14: ')
print(int('3'))
# print(int(s)) 这一句会报错…… 所以暂时注释掉了
print(float(s) * 9)
print(len(s))
print(s*3)``````
``````10
9
13
'A'

3
28.26
4
3.143.143.14``````

## 处理字符串的 Method

``'Python'.upper()``

### 大小写转换

``````s = 'Now is better than never.'
print(s.upper())

# 在 Python 命令行工具之中，单个下划线，是个特殊变量；
# 保存着最近的语句或者表达式的结果
# 上一个 Cell 执行过后，_ 中保存着 'NOW IS BETTER THAN NEVER.'
# 如果你使用命令行工具，可以执行 _.lower()

print(s.lower())``````
``````'NOW IS BETTER THAN NEVER.'

'now is better than never.'``````
``````
# casefold() 也是转换成小写，但它能处理更多欧洲语言字符

print('ß'.casefold())         # 德语字符中，大写 ß 的小写形式是 ss
print(len('ß'.casefold()))
print('ß'.lower())            # lower() 对这类字符无能为力……
print(len('ß'.lower())
# casefold
print('\u0132')               # Ĳ 这个字符的 Unicode 编码
print('\u0132'.casefold())
print('\u0132'.lower())        # 对这个字符来说，lower() 和 casefold 的效果一样
print(len('\u0132'.casefold()))

# 这是一篇有用的文章：
# Truths programmers should know about case
# https://www.b-list.org/weblog/2018/nov/26/case/``````
``````'ss'
2
'ß'
1
'Ĳ'
'ĳ'
'ĳ'
1``````
``````
s = 'Now is better than never.'
print(s)
s1 = s.capitalize() # 句首字母大写
print(s1)
s2 = s.title() # 每个单词首字母大写
print(s2)``````
``````'Now is better than never.'
'Now Is Better Than Never.'``````
``````s = 'Now is better than never.'
print(s)

s1 = s.swapcase() # 逐个字符更替大小写
print(s1)

s2 = s.title()
print(s2)

s3 = s.title().swapcase()
print(s3)``````
``````'nOW IS BETTER THAN NEVER.'
'Now Is Better Than Never.'
'nOW iS bETTER tHAN nEVER.'``````

``````# str.encode(encoding="utf-8", errors="strict")
# 关于更多可能的 encoding list, 请参阅：
# https://docs.python.org/3/library/codecs.html#standard-encodings
s = '简单优于复杂。'
s.encode()
print(s)``````
``b'\xe7\xae\x80\xe5\x8d\x95\xe4\xbc\x98\xe4\xba\x8e\xe5\xa4\x8d\xe6\x9d\x82\xe3\x80\x82'``

### 搜索与替换

`str.count(sub[,start[,end]])`

`str.count(sub [,start=0[, end=len(str)]])`

`=` 表示该参数有个默认值。上述这段说明如果你感到熟悉的话，说明前面的内容确实阅读到位了…… 与大量 “前置引用” 相伴随的是知识点的重复出现。

• 只给定 `sub` 一个参数的话，于是从第一个字符开始搜索到字符串结束；
• 如果，随后给定了一个可选参数的话，那么它是 `start`，于是从 `start` 开始，搜索到字符串结束；
• 如果 `start` 之后还有参数的话，那么它是 `end`；于是从 `start` 开始，搜索到 `end - 1` 结束（即不包含索引值为 `end` 的那个字符）。

``````
s = """Simple is better than complex.
Complex is better than complicated."""

a = s.lower().count('mp')

b = s.lower().count('mp', 10)

c = s.lower().count('mp', 10, 30)

print(a)
print(b)
print(c)
``````
``````4
3
1``````

``````
# str.find(sub[, start[, end]])
print('Example of str.find():')
s = """Simple is better than complex.
Complex is better than complicated."""
a = s.lower().find('mpl')
b = s.lower().find('mpl', 10)
c = s.lower().find('mpl', 10, 20) # 没有找到就返回 -1
print(a)
print(b)
print(c)
print()

print('Example of str.rfind():')
# str.rfind(sub[, start[, end]])
# rfind() 返回最后 sub 出现的那次的位置；find()是最早的那次
a = s.lower().rfind('mpl')
b = s.lower().rfind('mpl', 10)
c = s.lower().rfind('mpl', 10, 20) # 没有找到就返回 -1
print(a)
print(b)
print(c)
print()

print('Example of str.index():')
# str.index(sub[, start[, end]])
# 作用与 find() 相同，但如果没找到的话，会触发 ValueError 异常
# https://docs.python.org/3/library/exceptions.html#ValueError
a = s.lower().index('mpl')
# str.rindex(sub[, start[, end]])
# 作用与 rfind() 相同，但如果没找到的话，会触发 ValueError 异常
b = s.lower().rindex('mpl')
print(a)
print(b)
print()``````
``````Example of str.find():

2
24
-1
Example of str.rfind():
56
56
-1
Example of str.index():
2
56``````

`str.startswith()``str.endswith()` 是用来判断一个字符串是否以某个子字符串起始或者结束的：

``````s = """Simple is better than complex.
Complex is better than complicated."""

# str.startswith(prefix[, start[, end]])
print("s.lower().startswith('S'):", \
s.lower().startswith('S'))
print("s.lower().startswith('b', 10):", \
s.lower().startswith('b', 10))
print("s.lower().startswith('e', 11, 20):", \
s.lower().startswith('e', 11, 20))

# str.endswith(suffix[, start[, end]])
print("s.lower().endswith('.'):", \
s.lower().endswith('.'))
print("s.lower().endswith('.', 10):", \
s.lower().endswith('.', 10))
print("s.lower().endswith('.', 10, 20):", \
s.lower().endswith('.', 10, 20))

# 好玩：中国人一不小心就会把这两个函数写成或者记成
# startwith() 和 endwith() —— 少写一个 s!``````
``````s.lower().startswith('S'): False
s.lower().startswith('b', 10): True
s.lower().startswith('e', 11, 20): True
s.lower().endswith('.'): True
s.lower().endswith('.', 10): True
s.lower().endswith('.', 10, 20): False``````

``````s = """Simple is better than complex.
Complex is better than complicated."""
# 如果你只想知道 “有没有”，而无需知道 “在哪里”，那么可以用：
print('mpl' in s)``````
``True``

`str.replace(old, new[, count])`

`new` 替换 `old`，替换 `count` 个实例（实例：exmpale，每次处理的对象就是实例，即具体的操作对象），其中，`count` 这个参数是可选的。

``````s = """Simple is better than complex.
Complex is better than complicated."""

# str.startswith(prefix[, start[, end]])
print("s.lower().replace('mp', '[ ]', 2):\n")
print(s.lower().replace('mp', '[ ]', 2))``````
``````s.lower().replace('mp', '[ ]', 2):

si[ ]le is better than co[ ]lex.
complex is better than complicated.``````

`str.expandtabs( tabsize=8)`

``````# str.expandtabs(tabsize=8)
s = "Special\tcases\taren't\tspecial\tenough\tto\tbreak\tthe\trules."
print(s.expandtabs())
print(s.expandtabs(2))``````
``````"Special cases   aren't  special enough  to      break   the     rules."
"Special cases aren't  special enough  to  break the rules."``````

### 去除子字符

`str.strip([chars])`

``````s = "\r \t Simple is better than complex.    \t \n"
print(s)
print(s.strip())``````
``````'\r \t Simple is better than complex.    \t \n'

'Simple is better than complex.'``````

``````s = "Simple is better than complex."
print(s)
print(s.strip('Six.p'))    # p 全部处理完之后，p 并不在首尾，所以原字符串中的 p 字母不受影响；
print(s.strip('pSix.mle')) # 这一次，首尾的 p 被处理了…… 参数中的字符顺序对结果没有影响，换成 Sipx.mle 也一样……``````
``````'Simple is better than complex.'
'mple is better than comple'
' is better than co'``````

``````# str.lstrip([chars])
s = "Simple is better than complex."
print(s)
print(s.lstrip('Six.p'))    # p 全部处理完之后，p 并不在首部，所以原字符串中的 p 字母不受影响；
print(s.lstrip('pSix.mle')) # 这一次，首部的 p 被处理了…… 参数中的字符顺序对结果没有影响，换成 Sipx.mle 也一样……``````
``````'Simple is better than complex.'
'mple is better than complex.'
' is better than complex.'``````
``````# str.rstrip([chars])
s = "Simple is better than complex."
print(s)
print(s.rstrip('Six.p'))    # p 全部处理完之后，p 并不在尾部，所以原字符串中的 p 字母不受影响；
print(s.rstrip('pSix.mle')) # 这一次，尾部的 p 被处理了…… 参数中的字符顺序对结果没有影响，换成 Sipx.mle 也一样……``````
``````'Simple is better than complex.'
'Simple is better than comple'
'Simple is better than co'``````

### 拆分字符串

``````Name,Age,Location
John,18,New York
Mike,22,San Francisco
Janny,25,Miami
Sunny,21,Shanghai``````

`'Name,Age,Location\nJohn,18,New York\nMike,22,San Francisco\nJanny,25,Miami\nSunny,21,Shanghai'`

`str.splitlines()` 返回的是个列表（List）—— 这又是一个前面曾简要提起过，但会在后面的章节才能详细讲解的概念 —— 由被拆分的每一行作为其中的元素。

``````s = """Name,Age,Location
John,18,New York
Mike,22,San Francisco
Janny,25,Miami
Sunny,21,Shanghai"""

print(s)                 # s 被打印出来的时候，\n 都被转换成换行了
print(s.splitlines())    # 注意输出结果前后的方括号，[]，表示这个返回结果是一个 List``````
``````'Name,Age,Location\nJohn,18,New York\nMike,22,San Francisco\nJanny,25,Miami\nSunny,21,Shanghai'

['Name,Age,Location',
'John,18,New York',
'Mike,22,San Francisco',
'Janny,25,Miami',
'Sunny,21,Shanghai']``````

`str.split()`, 是将一个字符串，根据分隔符进行拆分：

`str.split(sep=None, maxsplit=-1)`

``````s = """Name,Age,Location
John,18,New York
Mike,22,San Francisco
Janny,25,Miami
Sunny,21,Shanghai"""

r = s.splitlines()[2]   # 取出返回列表中索引值为 2 的那一行
print(r)
print(r.split())               # 如果没有给 str.split() 传递参数，那么默认为用 None 分割（各种空白，比如，\t 和 \r 都被当作 None）
print(r.split(sep=','))
print(r.split(','))            # 上一行可以这样写。

print(r.split(sep=',', maxsplit=1))  # 第二个参数指定拆分几次
# r.split(sep=',', 1)         # 上一行不能这样写。
print(r.split(sep=',', maxsplit=0))  # 0 次，即不拆分
print(r.split(sep=',', maxsplit=-1)) # 默认值是 -1，拆分全部``````
``````'Mike,22,San Francisco'
['Mike,22,San', 'Francisco']
['Mike', '22', 'San Francisco']
['Mike', '22', 'San Francisco']
['Mike', '22,San Francisco']
['Mike,22,San Francisco']
['Mike', '22', 'San Francisco']``````

### 拼接字符串

`str.join()` 是将来非常常用的，它的官方文档说明却很少：

`str.join(_iterable_)`

Return a string which is the concatenation of the strings in iterable. A `TypeError` will be raised if there are any non-string values in iterable, including `bytes` objects. The separator between elements is the string providing this method.

``````s = ''
t = ['P', 'y', 't', 'h', 'o', 'n']
print(s.join(t))``````
``'Python'``

### 字符串排版

`str.center(width[, fillchar])`

``````s = 'Sparse is better than dense!'
print(s.title().center(60))
print(s.title().center(60, '='))
print(s.title().center(10)) # 如果宽度参数小于字符串长度，则返回原字符串

s = 'Sparse is better than dense!'
print(s.title().rjust(60))
print(s.title().rjust(60, '.'))``````
``````'                Sparse Is Better Than Dense!                '

'================Sparse Is Better Than Dense!================'

'Sparse Is Better Than Dense!'

'                                Sparse Is Better Than Dense!'

'................................Sparse Is Better Than Dense!'``````

• `str.ljust(width)`
• `str.rjust(width)`

``````for i in range(1, 11):
filename = str(i).zfill(3) + '.mp3'
print(filename)``````
``````001.mp3
002.mp3
003.mp3
004.mp3
005.mp3
006.mp3
007.mp3
008.mp3
009.mp3
010.mp3``````

### 格式化字符串

#### 使用 str.format()

`str.format(*args, **kwargs)`

• 在一个字符串中，插入一个或者多个占位符 —— 用大括号 `{}` 括起来；
• 而后将 `str.format()` 相应的参数，依次插入占位符中；

``````name = 'John'
age = 25
print('{} is {} years old.'.format(name, age))
# 不写占位符索引就默认每个占位符的索引从第一个开始是 0, 1, 2 ...（占位符数量 - 1)
# '{} {}'.format(a, b) 和 '{0} {1}'.format(a, b) 是一样的。

# '{0} is {2} years old.'.format(name, age)
# 这一句会报错，因为 2 超出实际参数索引极限

# 两个连续使用的大括号，不被认为是占位符；且只打印出一对大括号
print("Are you {0}? :-{{+}}".format(name))

# "%s is %d years old." % (name, age)
# 上一行这是兼容 Python 2 的老式写法，可以从此忽略……

# str.fomrat() 里可以直接写表达式……
print('{} is a grown up? {}'.format(name, age >= 18))``````
``````'John is 25 years old.'
'Are you John? :-{+}'
'John is a grown up? True'``````

#### 使用 f-string

f-string`str.format()` 的功用差不多，只是写法简洁一些 —— 在字符串标示之前加上一个字母 `f`

``````# https://docs.python.org/3/library/stdtypes.html#printf-style-bytes-formatting
# f-string

name = 'John'
age = 25
print(f'{name} is {age} years old.')
print(f'{name} is a grown up? {age >= 18}')``````
``````'John is 25 years old.'
'John is a grown up? True'``````

``````name = 'John'
age = 25
print('{1} is {0} years old.'.format(name, age))``````
``'25 is John years old.'``

### 字符串属性

``````# str.isalnum()
print("'1234567890'.isalnum():", \
'1234567890'.isalnum()) # '3.14'.isalnum() 返回的是 False

# str.isalpha()
print("'abcdefghij'.isalpha():", \
'abcdefghij'.isalpha())

# str.isascii(), GitPress 的 Python 不支持该函数
# print("'山巅一寺一壶酒'.isascii():", \
#       '山巅一寺一壶酒'.isascii())

# str.isdecimal()
print("'0.123456789'.isdecimal():", \
'0.1234567890'.isdecimal())

# str.isdigit()
print("'0.123456789'.isdigit():", \
'0.1234567890'.isdigit())       #  注意，如果字符串是 identifier，返回值也是 False

# str.isnumeric()
print("'0.123456789'.isnumeric():", \
'0.1234567890'.isnumeric())

# str.islower()
print("'Continue'.islower():", \
'Continue'.islower())

# str.isupper()
print("'Simple Is Better Than Complex'.isupper():", \
'Simple Is Better Than Complex'.isupper())

# str.istitle()
print("'Simple Is Better Than Complex'.istitle():", \
'Simple Is Better Than Complex'.istitle())

# str.isprintable()
print("'\t'.isprintable():", \
'\t'.isprintable())

# str.isspace()
print("'\t'.isspace():", \
'\t'.isspace())

# str.isidentifier()
print("'for'.isidentifier():", \
'for'.isidentifier())``````
``````'1234567890'.isalnum(): True
'abcdefghij'.isalpha(): True
'0.123456789'.isdecimal(): False
'0.123456789'.isdigit(): False
'0.123456789'.isnumeric(): False
'Continue'.islower(): False
'Simple Is Better Than Complex'.isupper(): False
'Simple Is Better Than Complex'.istitle(): True
'    '.isprintable(): False
'    '.isspace(): True
'for'.isidentifier(): True``````

## 总结

• 为了表格在一屏中可以正确显示，本来应该规规矩矩写 `str.xxx`，但写成了 `s.xxx`……
• 另外，操作那一行，为了分类记忆方便，把 `len()``s.join()` 也放进去了……

“记住” 的方法并不是马上就只盯着表格看…… 正确方法是反复阅读这一章内容中的代码，并逐一运行，查看输出结果；还要顺手改改看看，多多体会。多次之后，再看着表格回忆知识点，直到牢记为止。

## 为什么数值没有像字符串值这样详细论述？

Python 针对数字常用的操作符和内建函数，按照优先级从低到高排列：

`1 + 2` 3
`2 - 1` 1
`3 * 5` 15
`6 / 2` 3.0
`7 // 3` 2
`7 % 3` 1
`-6` -6
`+6` 6

`pow(2, 10)` 1024 `pow()`
`3 ** 2` 9

Python 用来处理数值的内建函数：

• `abs(n)` 函数返回参数 `n`绝对值
• `int(n)` 用来将浮点数字 `n` 换成整数
• `float(n)` 用来将整数 `n` 转换成浮点数字
• `divmod(n, m)` 用来计算 `n` 除以 `m`，返回两个整数，一个是，另外一个是
• `pow(n, m)` 用来做乘方运算，返回 `n``m` 次方
• `round(n)` 返回离浮点数字 `n` 最近的那个整数

Python 做更为复杂的数学计算的模块（Module）是 math module，参阅：

https://docs.python.org/3/library/math.html