第1课 字符串
在Python中,字符串是由一系列字符数据组成的不可变序列(可以理解为一种特殊的列表,这个列表只能存字符数据、且长度和内容不可变)
既然是序列,那么序列的通用操作同样适用于字符串:索引、切片、加号+
拼接、乘号*
重复、len()、max()、min()、not in
和in
成员资格检查。
不可变:字符串一旦创建,则长度不可变、内容也不可变,不能对字符串进行增、删和改的操作
之后讲的字符串对象函数,如果牵扯到所谓的增、删和改,一律都不是在原字符串的基础上做修改的,而是创建一个新的副本对象。
s = "abcd"
print(s[0])
# TypeError: 'str' object does not support item assignment
s[0] = 'A'
1 大小写转换方法
upper():将字符串中的所有小写字母转换为大写字母
s1 = "abcABCaBc123"
s2 = s1.upper()
print(s1)
print(s2)
lower():将字符串中的所有大写字母转换为小写字母
s1 = "abcABCaBc123"
s2 = s1.lower()
print(s1)
print(s2)
capitalize():将字符串中的第一个字符转为大写,其余字符转换为小写
print("one two three".capitalize())
print("1 2 3 one two three".capitalize())
title():将字符串中每个单词的首字母转换为大写,其余字母转小写
print("one two three".title())
print("1 2 3 one two three".title())
print("ONE tWO THrEe".title())
swapcase():将字符串中的大写字母转换为小写,小写字母转大写
print("one two three".swapcase())
print("1 2 3 one two three".swapcase())
print("ONE tWO THrEe".swapcase())
2 查找与替换方法
find(sub, start, end):查找子串sub在字符串中第一次出现的索引,如果未找到则返回-1。start查找的起始位置,默认为0,end查找的结束为止,默认为字符串结尾,这两个参数是可选的,用于确定查找范围的。
s = "my name is python and my friend named python"
print(s.find("python")) # 11
print(s.find("python",12))# 38
print(s.find("python",12, 37)) # -1
rfind(sub, start, end):从右往左,其他和find一致
s = "my name is python and my friend named python"
print(s.rfind("python")) # 38
print(s.rfind("python", 10,32)) # 11
index(sub, start, end):与find类似,但是未找到的话,它会报错
s = "my name is python and my friend named python"
print(s.index("python")) # 11
print(s.index("python",12))# 38
# ValueError: substring not found
print(s.index("python",12, 37)) # -1
rindex(sub, start, end):从右往左的index()
count(sub, start, end):返回子串sub在字符串中出现的次数。
s = "my name is python and my friend named python"
print(s.count("banana"))
replace(old, new, count):将字符串中的所有old子串替换为new子串。count是最大替换次数。
s = "one two three four five six seven eight nine ten"
s1 = s.replace("e", "666")
print(s1)
s2 = s.replace("e", "666", 3)
print(s2)
3 去除空白字符方法
strip(chars):去除字符串两端的指定字符,默认为空字符串,chars指定的字符串
s1 = " my name is bob "
s2 = s1.strip()
print(f"[{s2}]")
s3 = "###my name is bob###"
s2 = s3.strip("#")
print(f"[{s2}]")
lstrip(chars):删除左边的指定字符
rstrip(chars):删除右边的指定字符
4 分割和连接方法
split(sep, maxsplit):根据给定的分隔符sep将字符串分割成一个列表。maxsplit指的是最大切割次数,如果不指定分隔符的话,默认以空白字符作为分隔符。
s = "1 2 3 4 5 6 7 8"
arr = s.split(" ", maxsplit = 3)
print(arr)
s = "1\t2\n3\t4\t5\t6 7\t8"
arr = s.split()
print(arr)
splitlines(keepends):根据换行符将字符串进行分割,分割成列表。keepends可选,如果为True则保留换行符
s = """
鹅,鹅,鹅
曲项向天歌
白毛浮绿水
红掌拨清波
"""
s = "Apple\nBanana\nOrange\nPear"
print(s)
arr = s.splitlines()
print(arr)
join(iterable):将可迭代对象中的元素(必须是字符串)用指定的字符串进行连接
arr1 = ["computer", "refrigerator", "graph", "Machine Learning"]
print("+".join(arr1))
arr2 = [1,2,3,4,5,6]
# TypeError: sequence item 0: expected str instance, int found
# print("+".join(arr2))
print("+".join([str(i) for i in arr2]))
print("+".join(map(str, arr2)))
5 检查判断方法
startswith(prefix, start, end):判断字符串是否以prefix子串为开头
s = "迪丽热巴和我.avi"
print(s.startswith("迪丽"))
endswith(suffix, start, end):判断字符串是否以suffix子串结尾
s = "迪丽热巴和我.avi"
print(s.endswith(".avi"))
isalnum():检查字符串中的所有字符是否都是字母或数字。
s = "abc123"
print(s.isalnum()) # True
isalpha():检查字符串中的所有字符是否都是字母。
isdigit():检查字符串中的所有字符是否都是数字。
isdecimal():检查字符串中的所有字符是否都是十进制数字。
isnumeric():检查字符串中的所有字符是否都是数字字符。
isspace():检查字符串中的所有字符是否都是空白字符(空格 回车 换行)。
islower():检查字符串中的所有字符是否都是小写字母。
isupper():检查字符串中的所有字符是否都是大写字母。
6 对齐与填充
ljust(width, fillchar):将字符串左对齐,fillchar为指定填充的字符默认为空格,width指定宽度
word = "python"
print(f"[{word.ljust(20)}]")
print(f"[{word.ljust(20, "#")}]")
rjust(width, fillchar):将字符串右对齐
center(width, fillchar):将字符串居中对齐
7 Unicode编码与字符串大小
chr():将一个整数转换为对应的字符
ord():将一个字符转换为一个整数(Unicode编码 ASCII码)
arr1 = [ord(str(i)) for i in range(10)]
print(arr1)
s1 = "abcdefghijklmnopqrstuvwxyz"
s2 = s1.upper()
arr2 = [ord(i) for i in s1]
arr3 = [ord(i) for i in s2]
print(arr2)
print(arr3)
"""
[48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
[97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
"""
第2课 【字符串编程练习题】
练习01 回文字符串
输入一个字符串,判断其是否是回文字符串。
# 思路1
# s1 = "黄山落叶松叶落山黄"
# s2 = s1[::-1] # 反转
# print(s2)
# print(s1 == s2)
# 思路2
def is_palindrome(s):
l = 0
r = len(s) - 1
while l < r:
if s[l] != s[r]:
return False
l += 1
r -= 1
return True
s1 = "2黄山落叶松叶落山黄1"
# l r
print(is_palindrome(s1))
练习02 十进制转二进制
题目描述
输入一个十进制正整数,输出其二进制形式
输入输出描述
输入一个十进制正整数
输出二进制字符串
示例
输入:
9
输出:
1001
def to_binary(num):
s = ""
while num != 0:
y = num % 2
s = str(y) + s # 重点
print(y)
num //= 2
return s
num = 123
print(to_binary(num))
练习03 二进制转十进制
题目描述
输入一个二进制字符串,输出其对应的十进制数字
输入输出描述
输入一个二进制字符串
输出十进制数字
示例
输入:
1001
输出:
9
def to_decimal(s):
s = s[::-1]
#"11101101"
num = 0
for i in range(len(s)):
num += int(s[i]) * 2 ** i
return num
s = "10110111"
print(to_decimal(s))
print(int(s, 2))
练习04 十进制转十六进制
题目描述
输入一个十进制正整数,输出其十六进制形式
输入输出描述
输入一个十进制正整数
输出十六进制字符串
示例
输入:
1233321
输出:
1e1b9
def to_hex(num):
s = ""
while num != 0:
y = num % 16
if y < 10:
s = str(y) + s
else: # 10 -> A 11 -> B
s = chr(55 + y) + s
num //= 16
return s.lower()
num = 1928916238751286
print(to_hex(num))
print(hex(num)[2:])
# 十六进制转十进制
def to_decimal(s):
s = s[::-1]
num = 0
for i in range(len(s)):
if s[i].isdigit():
num += int(s[i]) * 16 ** i
else: # a - 10 b - 11
num += (ord(s[i]) - 87) * 16 ** i
return num
s = "6da56cf365636"
print(to_decimal(s))
print(int(s, 16))
练习05 最长公共前缀
题目描述
给定两个字符串 s1 和 s2 ,求两个字符串最长的公共前缀串,字符区分大小写
输入输出描述
输入两行,分别表示s1和s2
输出前缀串
示例
输入:
abcdefg
abcdhko
输出:
abcd
def sovle(s1, s2):
p1 = 0
p2 = 0
while p1 < len(s1) and p2 < len(s2):
if s1[p1] != s2[p2]:
break
p1 += 1
p2 += 1
return s1[:p1]
s1 = "123456"
s2 = "789123"
suffix = sovle(s1, s2)
print(suffix)
练习06 子串出现的次数
题目描述
给定两个字符串 s1 和 s2 ,求 s2 在 s1 中出现的次数,字符区分大小写,已匹配的字符不计入下一次匹配
输入输出描述
输入两行字符串,分别为s1和s2,s2的长度小于等于s1
输出s2在s1中出现的次数
示例1
输入:
ABCsdABsadABCasdhjabcsaABCasd
ABC
输出:
3
示例2
输入:
AAAAAAAA
AAA
输出:
2
# 贪心的思路
# def sovle(s1, s2): # O(n^2)
# count = 0
# for i in range(len(s1) - len(s2) + 1):
# sub = s1[i:i + len(s2)]
# if sub == s2:
# count += 1
# return count
# 非贪心思路 O(n^2)
# def sovle(s1, s2):
# count = 0
# i = 0
# while i < len(s1) - len(s2) + 1:
# sub = s1[i:i + len(s2)]
# if sub == s2:
# count += 1
# i = i + len(s2)
# else:
# i += 1
# return count
def sovle(s1, s2):
count = 0
i = 0
while i < len(s1) - len(s2) + 1:
j = i
k = 0
while k < len(s2):
if s1[j] != s2[k]:
i += 1
break
j += 1
k += 1
else:
count += 1
i = j
# i += 1 # 贪心就这么写就对了
return count
s1 = "AAAAAAAA"
s2 = "AAA"
count = sovle(s1, s2)
print(count)
"""
关于字符串匹配的问题,有专门的算法
KMP
"""
练习07 最长公共子串
题目描述
给定两个字符串 s1 和 s2 ,求 s1 与 s2 之间的最长公共子串,字符区分大小写
输入输出描述
输入两行字符串,分别为s1和s2
输出最长公共子串
示例
输入:
123ABCDEFG83hsad
iughABCDEFG23uy
输出:
ABCDEFG
# 暴力破解 枚举
def solve(s1, s2):
# 默认长度 s1 > s2
for length in range(len(s2), 0, -1):
left = 0
right = length - 1
while right < len(s2):
sub = s2[left:right + 1]
print(sub)
if s1.find(sub) != -1:
return sub
left += 1
right += 1
return ""
s1 = "12345678910"
s2 = "abc"
print(solve(s1, s2))
练习08 猜单词游戏
题目描述
随机产生一个单词,然后提示用户一次猜一个字母,如下示例所示。单词中的每个字母都显示为一个#号,当用户猜测正确时就会显示确切的字母,当用户完成一个单词时,显示失误的次数并询问用户是否继续玩游戏
创建一个数组存储备选单词,然后随机从中抽取进行游戏
示例
Enter a letter in word ####### > p
Enter a letter in word p###### > r
Enter a letter in word pr##r## > p
p is already in the word
Enter a letter in word pr##r## > o
Enter a letter in word pro#r## > g
Enter a letter in word progr## > n
n is not in the word
Enter a letter in word progr## > m
Enter a letter in word progr#m > a
The word is program. You missd 1 time.
Do you want to guess another word? Enter y or n >
import random
# 获取单词的密文字符串
def get_passwd(word, status):
passwd = ""
for i in range(len(word)):
if status[i]:
passwd += word[i]
else:
passwd += "#"
return passwd
# 改变单词状态数组
def change_status(letter, status, word):
for i in range(len(word)):
if word[i] == letter:
# 是否已经改过
if status[i]:
# 已经改过了 后面就不用看了
return False
else:
# 没改过 后面也都没改过
status[i] = True
return True
# 针对word这个单词来进行游戏
def start_game(word):
# 错误的次数
missed = 0
# 单词字母的状态列表
status = [False] * len(word)
# 具体的输入字母进行猜单词
while False in status:
# 获取当前单词的密文
passwd = get_passwd(word, status)
# 提示输入一个字母
letter = input(f"请输入字母 {passwd}>>>")
# 判断字母的存在性
if letter in word:
# 考虑修改状态数组了 True 改了 False没改
if not change_status(letter, status, word):
print(f"{letter}已经存在!")
else:
missed += 1
print(f"{letter}不在单词中!")
print(f"你猜对了,这个单词就是{word},你猜错了{missed}次")
def main():
words = ["banana", "python","apple","computer"]
while True:
# 随机抽取一个单词 [a, b]
index = random.randint(0, len(words) - 1)
word = words[index]
# 开始猜单词的游戏
start_game(word)
# 是否继续
choice = input("是否继续游戏? y/n >>>")
if choice == "n":
break
main()