Day5 长篇:字符串和常用数据结构

简介: Day5 长篇:字符串和常用数据结构

在Python程序中,如果我们把单个或多个字符用单引号或者双引号包围起来,就可以表示一个字符串。

s1 = '你好'
s2 = "你好"
# 三个单引号或三个双引号的字符串可以换行
s3 = '''
你
好
'''

输出:
你好 你好 
你
好

一、转义字符

在字符串中使用\(反斜杠)来表示转义,也就是说\后面的字符不再是它原来的意义,例如:\n不是代表反斜杠和字符n,而是表示换行;而\t也不是代表反斜杠和字符t,而是表示制表符。所以如果想在字符串中表示'要写成\',同理想表示\要写成\\。可以运行下面的代码看看会输出什么。

在 Python 中,end=''print() 函数的一个参数,用于控制输出的结束方式。具体来说,它的作用是防止 print() 函数在输出完毕后自动换行,而是在输出的末尾添加一个空字符串。

end='' 常常位于 print() 函数的末尾,与前一个函数用 ',' 隔开。

s1 = '\'你好\''
s2 = '\n\\你好\\\n'
print(s1, s2, end='')

输出:
'你好' 
\你好\

\后面还可以跟一个八进制或者十六进制数来表示字符,例如\141\x61都代表小写字母a,前者是八进制的表示法,后者是十六进制的表示法。也可以在\后面跟Unicode字符编码来表示字符。

s1 = '\141\142\143\x61\x62\x63'
s2 = '\u4e2d\u56fd'
print(s1, s2)

输出:
abcabc 中国

如果不希望字符串中的\表示转义,我们可以通过在字符串的最前面加上字母r来加以说明

s1 = r'\'hello, world!\''
s2 = r'\n\\hello, world!\\\n'
print(s1, s2, end='')

输出:
\'hello, world!\' \n\\hello, world!\\\n

二、切片

Python为字符串类型提供了非常丰富的运算符,我们可以使用+运算符来实现字符串的拼接,可以使用*运算符来重复一个字符串的内容,可以使用innot in来判断一个字符串是否包含另外一个字符串(成员运算),我们也可以用[][:]运算符从字符串取出某个字符或某些字符(切片运算)。

s1 = 'hello ' * 3
print(s1) # hello hello hello 
s2 = 'world'
s1 += s2
print(s1) # hello hello hello world
print('ll' in s1) # True
print('good' in s1) # False
str2 = 'abc123456'
# 从字符串中取出指定位置的字符(下标运算)
print(str2[2]) # c
# 字符串切片(从指定的开始索引到指定的结束索引)
print(str2[2:5]) # c12
print(str2[2:]) # c123456
print(str2[2::2]) # c246
print(str2[::2]) # ac246
print(str2[::-1]) # 654321cba
print(str2[-3:-1]) # 45

三、字符串的处理

在Python中,我们还可以通过一系列的方法来完成对字符串的处理。

str1 = 'hello, world!'
# 通过内置函数len计算字符串的长度
print(len(str1)) # 13
# 获得字符串首字母大写的拷贝
print(str1.capitalize()) # Hello, world!
# 获得字符串每个单词首字母大写的拷贝
print(str1.title()) # Hello, World!
# 获得字符串变大写后的拷贝
print(str1.upper()) # HELLO, WORLD!
# 从字符串中查找子串所在位置
print(str1.find('or')) # 8
print(str1.find('shit')) # -1
# 与find类似但找不到子串时会引发异常
# print(str1.index('or'))
# print(str1.index('shit'))
# 检查字符串是否以指定的字符串开头
print(str1.startswith('He')) # False
print(str1.startswith('hel')) # True
# 检查字符串是否以指定的字符串结尾
print(str1.endswith('!')) # True
# 将字符串以指定的宽度居中并在两侧填充指定的字符
print(str1.center(50, '*'))
# 将字符串以指定的宽度靠右放置左侧填充指定的字符
print(str1.rjust(50, ' '))
str2 = 'abc123456'
# 检查字符串是否由数字构成
print(str2.isdigit())  # False
# 检查字符串是否以字母构成
print(str2.isalpha())  # False
# 检查字符串是否以数字和字母构成
print(str2.isalnum())  # True
str3 = '  xxx@xxx.com '
print(str3)
# 获得字符串修剪左右两侧空格之后的拷贝
print(str3.strip())

四、格式化输出

a, b = 5, 10
print('%d * %d = %d' % (a, b, a * b))

输出结果:
5 * 10 = 50

当然,我们也可以用字符串提供的方法来完成字符串的格式,代码如下所示。

a, b = 5, 10
print('{0} * {1} = {2}'.format(a, b, a * b))

输出结果:
5 * 10 = 50

Python 3.6以后,格式化字符串还有更为简洁的书写方式,就是在字符串前加上字母f,我们可以使用下面的语法糖来简化上面的代码。

a, b = 5, 10
print(f'{a} * {b} = {a * b}')

输出结果:
5 * 10 = 50

五、列表list

列表是值的有序序列,每个值都可以通过索引进行标识,定义列表可以将列表的元素放在[]中,多个元素用逗号分隔,可以使用for循环对列表进行遍历,也可以使用[],[:]运算符对列表中的一个或多个元素操作。

1、列表的基本运算

list1 = [1,2,3]
print(list1)
list2 = ['world'] * 2
print(list2)
print(len(list1))
print(list1[0])
print(list1[-2])
list1[2] = 666
print(list1)
for index in range(len(list1)):
    print(list1[index])
for elem in list1:
    print(elem)
for index,elem in enumerate(list1):
    print(index,elem)
# 通过enumerate函数处理列表之后再遍历可以同时获得元素索引和值
    
输出结果:
[1, 2, 3]
['world', 'world']
3
1
2
[1, 2, 666]
1
2
666
1
2
666
0 1
1 2
2 666

2、列表的添加、删除元素

list1 = [1,3,5,7,9,100]
#添加元素
list1.append(666)
list1.insert(888,999)
# 合并两个列表
list1 += [111,222]
print(list1)
print(len(list1))
if 100 in list1:
    list1.remove(100)
print(list1)
#从指定位置删除元素
list1.pop(0)
print(list1)
list1.pop(len(list1)-1)
print(list1)
#清空列表
list1.clear()
print(list1)

输出:
[1, 3, 5, 7, 9, 100, 666, 999, 111, 222]
10
[1, 3, 5, 7, 9, 666, 999, 111, 222]
[3, 5, 7, 9, 666, 999, 111, 222]
[3, 5, 7, 9, 666, 999, 111]
[]

3、列表的切片

animals = ['monkey','rabbit','tiger','lion']
animals += ['snake','elephant','giraffe']
#切片
animals2 = animals[1:4]
print(animals2)
#通过完整切片来复制列表
animals3 = animals[:]
print(animals3)
animals4 = animals[-2:-1]
print(animals4)
#通过反向切片获得倒转的列表
animals5 = animals[::-1]
print(animals5)

输出结果:
['rabbit', 'tiger', 'lion']
['monkey', 'rabbit', 'tiger', 'lion', 'snake', 'elephant', 'giraffe']
['elephant']
['giraffe', 'elephant', 'snake', 'lion', 'tiger', 'rabbit', 'monkey']

4、列表的排序

animals = ['monkey','rabbit','tiger','lion','snake','elephant','giraffe']
# sorted函数返回列表排序后的拷贝不会修改传入的列表
animals2 = sorted(animals)
# 在列表的 reverse() 方法中,设置 reverse=True 可以将列表中的元素倒序排列
animals3 = sorted(animals,reverse=True)
# # 通过key关键字参数指定根据字符串长度进行排序而不是默认的字母表顺序
animals4 = sorted(animals,key=len)
print(animals)
print(animals2)
print(animals3)
print(animals4)
# 给列表对象发出排序消息直接在列表对象上进行排序
animals.sort(reverse=True)
print(animals)

输出结果:
['monkey', 'rabbit', 'tiger', 'lion', 'snake', 'elephant', 'giraffe']
['elephant', 'giraffe', 'lion', 'monkey', 'rabbit', 'snake', 'tiger']
['tiger', 'snake', 'rabbit', 'monkey', 'lion', 'giraffe', 'elephant']
['lion', 'tiger', 'snake', 'monkey', 'rabbit', 'giraffe', 'elephant']
['tiger', 'snake', 'rabbit', 'monkey', 'lion', 'giraffe', 'elephant']

六、生成式和生成器

利用列表的生成式语法创建列表

f = [x for x in range(1, 10)]
print(f)
f = [x + y for x in 'ABCDE' for y in '1234567']
print(f)
f = [x ** 2 for x in range(1, 1000)]
print(f)

或者利用yield关键字将一个普通函数改造成生成器函数

def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
        yield a

def main():
    for val in fib(20):
        print(val)

if __name__ == '__main__':
    main()

七、元组

python中的元组和列表类似,也是一种容器数据,可以用一个变量来存储多个数据,元组中的元素不能修改。

#定义元组
t = ('伟大',1949,True,'北京')
print(t)
# 获取元组中的某个元素
print(t[2])
#遍历元组中的值
for x in t:
    print(x)
#重新给元组赋值
#不能t[0] = 'xxx',而是需要把元组转换为列表后再赋值
t_list = list(t)
print(t_list)
t_list[0] = '中国'
t_list[1] = 2024
print(t_list)
t2 = tuple(t_list)
print(t2)

输出:
('伟大', 1949, True, '北京')
True
伟大
1949
True
北京
['伟大', 1949, True, '北京']
['中国', 2024, True, '北京']
('中国', 2024, True, '北京')

思考:为什么已经有了列表这种数据结构,还需要元组呢?

  1. 不可变性的优势:元组的不可变性使得它在某些情况下更安全和可靠。当你需要确保数据在程序执行过程中不会被意外修改时,使用元组可以避免因误操作导致的数据不一致。
  2. 性能方面:元组的结构相对简单,在一些场景下,比如频繁读取数据而较少修改的情况下,元组的性能可能会略好于列表。
  3. 用途方面:元组常常用于表示一些相互关联的、具有固定顺序的元素,比如坐标、日期等。它可以明确地传达数据的结构和意义,并且由于其不可变性,有助于保持数据的完整性。而列表则更适合用于动态地存储和操作数据,如添加、删除元素等。

八、集合

在 Python 中,集合(set)是一种无序且不包含重复元素的数据结构。

集合具有以下特点:

  1. 不允许重复元素:集合会自动去除重复的元素。
  2. 无序性:集合中的元素没有固定的顺序。

集合支持一些常见的操作,如添加元素、删除元素、集合的并集、交集、差集等。

# 创建集合的字面量语法
set1 = {1, 2, 3, 3, 3, 2}
print(set1)
print('Length =', len(set1))
# 创建集合的构造器语法(面向对象部分会进行详细讲解)
set2 = set(range(1, 10))
set3 = set((1, 2, 3, 3, 2, 1))
print(set2, set3)
# 创建集合的推导式语法(推导式也可以用于推导集合)
set4 = {num for num in range(1, 100) if num % 3 == 0 or num % 5 == 0}
print(set4)

# 添加删除元素
set1.add(4)
set1.add(5)
set2.update([11, 12])
set2.discard(5)
if 4 in set2:
    set2.remove(4)
print(set1, set2)
print(set3.pop())
print(set3)

# 集合的交集、并集、差集、对称差运算
print(set1 & set2)
# print(set1.intersection(set2))
print(set1 | set2)
# print(set1.union(set2))
print(set1 - set2)
# print(set1.difference(set2))
print(set1 ^ set2)
# print(set1.symmetric_difference(set2))
# 判断子集和超集
print(set2 <= set1)
# print(set2.issubset(set1))
print(set3 <= set1)
# print(set3.issubset(set1))
print(set1 >= set2)
# print(set1.issuperset(set2))
print(set1 >= set3)
# print(set1.issuperset(set3))

输出结果:
{1, 2, 3}
Length = 3
{1, 2, 3, 4, 5, 6, 7, 8, 9} {1, 2, 3}
{3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27, 30, 33, 35, 36, 39, 40, 42, 45, 48, 50, 51, 54, 55, 57, 60, 63, 65, 66, 69, 70, 72, 75, 78, 80, 81, 84, 85, 87, 90, 93, 95, 96, 99}
{1, 2, 3, 4, 5} {1, 2, 3, 6, 7, 8, 9, 11, 12}
1
{2, 3}
{1, 2, 3}
{1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12}
{4, 5}
{4, 5, 6, 7, 8, 9, 11, 12}
False
True
False
True

九、字典

Python 中的字典(dict)是一种非常重要的数据结构。

字典是由键值对组成的,它具有以下特点:

  1. 键的唯一性:字典中的键必须是唯一的。
  2. 无序性:字典中的元素没有固定的顺序。

字典的每个元素都是由一个键和一个值组成的“键值对”,键和值通过冒号分开。字典提供了高效的键值查找、添加、修改和删除操作。

# 创建字典的字面量语法
scores = {'梅西':'足球', '奥沙利文':'台球','乔丹':'篮球'}
print(scores)
# 创建字典的构造器语法
items1 = dict(one=1, two=2, three=3, four=4)
# 通过zip函数将两个序列压成字典
items2 = dict(zip(['a', 'b', 'c'], '123'))
# 创建字典的推导式语法
items3 = {num: num ** 2 for num in range(1, 10)}
print(items1, items2, items3)
# 通过键可以获取字典中对应的值
print(scores['梅西'])
print(scores['奥沙利文'])
# 对字典中所有键值对进行遍历
for key in scores:
    print(f'{key}: {scores[key]}')
# 更新字典中的元素
scores['刘翔'] = '田径'
scores['Simple'] = '电竞'
scores.update(郭晶晶='跳水', 马龙='乒乓球')
print(scores)
if '柯洁' in scores:
    print(scores['柯洁'])
print(scores.get('柯洁'))
# get方法也是通过键获取对应的值但是可以设置默认值
print(scores.get('柯洁', '围棋'))
# 删除字典中的元素
print(scores.popitem())
print(scores.popitem())
print(scores.pop('梅西', '足球'))
# 清空字典
scores.clear()
print(scores)

输出结果:
{'梅西': '足球', '奥沙利文': '台球', '乔丹': '篮球'}
{'one': 1, 'two': 2, 'three': 3, 'four': 4} {'a': '1', 'b': '2', 'c': '3'} {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
足球
台球
梅西: 足球
奥沙利文: 台球
乔丹: 篮球
{'梅西': '足球', '奥沙利文': '台球', '乔丹': '篮球', '刘翔': '田径', 'Simple': '电竞', '郭晶晶': '跳水', '马龙': '乒乓球'}
None
围棋
('马龙', '乒乓球')
('郭晶晶', '跳水')
足球
{}
相关文章
|
3月前
|
存储 缓存 NoSQL
redis数据结构-字符串
redis数据结构-字符串
38 1
|
10天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
32 6
|
5月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
83 1
|
5月前
|
存储 JavaScript 前端开发
JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)
【6月更文挑战第25天】JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)。
40 2
|
5月前
数据结构 字符串 (第6天)
数据结构 字符串 (第6天)
|
5月前
|
存储 算法 Java
Java数据结构与算法:用于高效地存储和检索字符串数据集
Java数据结构与算法:用于高效地存储和检索字符串数据集
|
6月前
题目----数据结构线性表----字符串逆序
题目----数据结构线性表----字符串逆序
33 1
|
5月前
|
算法 Java
Java数据结构与算法:字符串匹配算法之暴力匹配
Java数据结构与算法:字符串匹配算法之暴力匹配
|
5月前
|
算法 Java
Java数据结构与算法:字符串匹配算法之KMP算法
Java数据结构与算法:字符串匹配算法之KMP算法
|
6月前
|
存储 索引 Python
Python数据结构——字符串
Python数据结构——字符串
54 0