1. 字符串反转
字符串是 python 中最常用的序列类型,反转操作非常高频,以下是三种核心方法。
1.1 方法1:切片[::-1](最推荐!)
这是 python 中最简洁高效的字符串反转方式,利用切片的**步长(step)**参数实现。
切片语法回顾: s[start:end:step]
start:起始索引(省略则从开头)end:结束索引(省略则到末尾)step:步长,-1表示从后往前取
代码示例:
s = "hello python"
# 切片反转:start和end省略,step=-1
reversed_s = s[::-1]
print(f"原字符串: {s}")
print(f"反转后: {reversed_s}")
# 输出:
# 原字符串: hello python
# 反转后: nohtyp olleh解析:
- 切片
[::-1]会从字符串最后一个字符开始,向前遍历所有字符,生成新的反转字符串。 - 优点:代码一行搞定,时间复杂度 o(n),效率极高。
1.2 方法2:reversed()+join()
reversed() 是 python 内置函数,返回一个反向迭代器,需要用 join() 将迭代器拼接成字符串。
代码示例:
s = "hello python"
# 1. reversed(s) 返回反向迭代器
# 2. ''.join() 将迭代器中的字符拼接成字符串
reversed_s = ''.join(reversed(s))
print(f"原字符串: {s}")
print(f"反转后: {reversed_s}")
# 输出: nohtyp olleh解析:
reversed(s)不会直接生成列表,而是返回迭代器(节省内存),适合处理超长字符串。join()用于将可迭代对象(如迭代器、列表)的元素拼接成字符串。
1.3 方法3:手动循环拼接(理解原理用)
通过索引从后往前遍历字符,逐个拼接成新字符串,适合理解反转逻辑。
代码示例:
s = "hello python"
reversed_s = ""
# 从最后一个索引(len(s)-1)开始,遍历到 0
for i in range(len(s)-1, -1, -1):
reversed_s += s[i]
print(f"原字符串: {s}")
print(f"反转后: {reversed_s}")
# 输出: nohtyp olleh解析:
range(len(s)-1, -1, -1):起始是最后一个索引,结束是-1(不包含,所以到 0),步长-1。- 优点:直观理解反转过程;缺点:代码冗长,效率略低(字符串拼接会生成新对象)。
字符串反转总结: 日常开发优先用切片 [::-1],简洁高效。
2. 四大数据结构反转
2.1 列表反转
列表是可变序列,反转方法分为原地反转(修改原列表)和非原地反转(返回新列表)。
方法1:切片[::-1](非原地,返回新列表)
和字符串切片类似,返回一个新的反转列表,不修改原列表。
代码示例:
lst = [1, 2, 3, 4, 5]
# 切片反转,返回新列表
reversed_lst = lst[::-1]
print(f"原列表: {lst}") # 原列表不变: [1, 2, 3, 4, 5]
print(f"反转后新列表: {reversed_lst}") # [5, 4, 3, 2, 1]解析:
优点:不修改原列表,代码简洁;缺点:生成新列表,占用额外内存。
方法2:list.reverse()(原地反转,修改原列表)
列表的内置方法,直接修改原列表,返回 none(新手易错!)。
代码示例:
lst = [1, 2, 3, 4, 5]
# 原地反转,修改原列表,返回 none
result = lst.reverse()
print(f"原列表(已修改): {lst}") # [5, 4, 3, 2, 1]
print(f"返回值: {result}") # none(注意!不是反转后的列表)解析:
优点:不需要额外内存,直接修改原列表;缺点:会改变原列表,且返回值是 none,不能写 a = lst.reverse()。
方法3:reversed()+list()(非原地,返回迭代器转列表)
reversed() 返回反向迭代器,用 list() 转成新列表,不修改原列表。
代码示例:
lst = [1, 2, 3, 4, 5]
# reversed() 返回迭代器,list() 转成新列表
reversed_lst = list(reversed(lst))
print(f"原列表: {lst}") # [1, 2, 3, 4, 5]
print(f"反转后新列表: {reversed_lst}") # [5, 4, 3, 2, 1]解析:
适合需要迭代器的场景(如遍历大列表时节省内存),转列表后和切片效果一致。
列表反转总结:
- 不想修改原列表:用
lst[::-1]或list(reversed(lst))。 - 想直接修改原列表:用
lst.reverse()(注意返回值是none)。
2.2 元组反转
元组是不可变序列,没有 reverse() 方法(不能原地修改),只能通过非原地方式返回新元组。
方法1:切片[::-1](推荐)
和字符串、列表切片一致,返回新的反转元组。
代码示例:
t = (1, 2, 3, 4, 5)
# 切片反转,返回新元组
reversed_t = t[::-1]
print(f"原元组: {t}") # (1, 2, 3, 4, 5)
print(f"反转后新元组: {reversed_t}") # (5, 4, 3, 2, 1)方法2:reversed()+tuple()
reversed() 返回迭代器,用 tuple() 转成新元组。
代码示例:
t = (1, 2, 3, 4, 5)
reversed_t = tuple(reversed(t))
print(f"反转后: {reversed_t}") # (5, 4, 3, 2, 1)元组反转总结: 优先用切片 [::-1],简洁高效。
2.3 集合反转(说明)
重要:集合(set)是无序的! 集合中的元素没有固定顺序,因此“集合反转”本身没有意义。
如果强行将集合转成列表反转,再转回集合,最终集合的顺序仍然是不确定的(python 内部优化决定)。
代码示例(仅演示,无实际意义):
s = {1, 2, 3, 4, 5}
# 1. 集合转列表
lst = list(s)
# 2. 列表反转
reversed_lst = lst[::-1]
# 3. 转回集合(顺序又变了!)
s_new = set(reversed_lst)
print(f"原集合: {s}") # 例如 {1,2,3,4,5}(顺序不确定)
print(f"反转列表后转回集合: {s_new}") # 顺序仍然不确定结论:集合不需要反转操作,如果需要有序的“集合”,可以用 list 或 collections.ordereddict(python 3.7+ 字典已有序)。
2.4 字典反转
python 3.7+ 中,字典(dictionary)是有序的(按插入顺序存储键值对)。字典反转分为两种场景:
- 键值对反转:将
{k: v}变成{v: k}。 - 按插入顺序反转项:将键值对的顺序倒过来。
键值对反转(k:v→v:k)
通过字典推导式实现,注意:值必须唯一,否则后面的会覆盖前面的!
代码示例:
# 原字典:键唯一,值也唯一
original_dict = {"a": 1, "b": 2, "c": 3}
# 字典推导式:键值互换
reversed_dict = {v: k for k, v in original_dict.items()}
print(f"原字典: {original_dict}") # {'a': 1, 'b': 2, 'c': 3}
print(f"键值反转后: {reversed_dict}") # {1: 'a', 2: 'b', 3: 'c'}解析:
original_dict.items()获取键值对(k, v)。- 推导式中写成
{v: k},实现键值互换。
易错点:值不唯一时会覆盖!
# 原字典:值有重复('a' 和 'b' 对应的值都是 1)
original_dict = {"a": 1, "b": 1, "c": 3}
# 键值反转后,后面的 'b':1 会覆盖前面的 'a':1
reversed_dict = {v: k for k, v in original_dict.items()}
print(f"原字典: {original_dict}") # {'a': 1, 'b': 1, 'c': 3}
print(f"键值反转后: {reversed_dict}") # {1: 'b', 3: 'c'}('a' 被覆盖了!)按插入顺序反转项(python 3.7+)
将字典的键值对按插入顺序倒过来,保持键值关系不变,只改变顺序。
代码示例:
# 原字典(按插入顺序:a→b→c)
original_dict = {"a": 1, "b": 2, "c": 3}
# 1. items() 转成列表,列表可以反转
items_list = list(original_dict.items()) # [('a',1), ('b',2), ('c',3)]
# 2. 反转列表
reversed_items = items_list[::-1] # [('c',3), ('b',2), ('a',1)]
# 3. 转回字典
reversed_dict = dict(reversed_items)
print(f"原字典: {original_dict}") # {'a': 1, 'b': 2, 'c': 3}
print(f"顺序反转后: {reversed_dict}") # {'c': 3, 'b': 2, 'a': 1}
# 一行代码搞定
reversed_dict_one_line = dict(list(original_dict.items())[::-1])
print(f"一行代码: {reversed_dict_one_line}") # 同上解析:
- 字典的
items()本身是视图对象,转成列表后才能反转。 - 反转列表后用
dict()转回,保持键值关系,顺序倒过来。
字典反转总结:
- 键值互换:用字典推导式
{v: k for k, v in d.items()}(注意值唯一)。 - 顺序反转:转列表反转后再转回字典
dict(list(d.items())[::-1])。
3. 文件内容反转并复制
将一个文件的内容反转后写入另一个文件,分为三种常见场景:
- 整个文件内容作为字符串反转。
- 行顺序反转(第一行变最后一行,行内容不变)。
- 每行内容反转(行顺序不变,每行内部字符反转)。
前置准备: 先创建一个测试文件 original.txt,内容如下:
第一行内容
第二行内容
第三行内容
3.1 场景1:整个文件内容反转
将文件所有内容作为一个大字符串,反转后写入新文件(适合小文件)。
代码示例:
# 1. 读取原文件全部内容
with open("original.txt", mode='r', encoding='utf-8') as f:
content = f.read()
# 2. 反转整个字符串
reversed_content = content[::-1]
# 3. 写入新文件
with open("reversed_whole.txt", mode='w', encoding='utf-8') as f:
f.write(reversed_content)
print("整个内容反转完成!")结果 reversed_whole.txt:
容内行三第
容内行二第
容内行一第
3.2 场景2:行顺序反转(推荐!)
保持每行内容不变,将行的顺序倒过来(第一行变最后一行),这是最常用的文件反转场景。
代码示例:
# 1. 读取所有行到列表(每个元素是一行,包含换行符)
with open("original.txt", mode='r', encoding='utf-8') as f:
lines = f.readlines()
# 查看 lines 内容:
# ['第一行内容\n', '第二行内容\n', '第三行内容']
# 2. 反转行列表
reversed_lines = lines[::-1]
# 3. 写入新文件
with open("reversed_lines.txt", mode='w', encoding='utf-8') as f:
f.writelines(reversed_lines)
print("行顺序反转完成!")结果 reversed_lines.txt:
第三行内容
第二行内容
第一行内容
解析:
readlines() 读取的行包含换行符 \n,反转后直接 writelines() 写入即可,换行符会保留。
3.3 场景3:每行内容反转
保持行顺序不变,将每行内部的字符反转。
代码示例:
# 1. 读取所有行
with open("original.txt", mode='r', encoding='utf-8') as f:
lines = f.readlines()
# 2. 处理每一行:反转内容,保留换行符
processed_lines = []
for line in lines:
# 先去除换行符,反转,再加上换行符(如果原行有)
if line.endswith('\n'):
reversed_line = line.rstrip('\n')[::-1] + '\n'
else:
reversed_line = line[::-1]
processed_lines.append(reversed_line)
# 3. 写入新文件
with open("reversed_each_line.txt", mode='w', encoding='utf-8') as f:
f.writelines(processed_lines)
print("每行内容反转完成!")结果 reversed_each_line.txt:
容内行一第
容内行二第
容内行三第
3.4 大文件处理注意事项
如果文件非常大(比如几个 gb),read() 或 readlines() 会一次性加载到内存,导致内存溢出。此时可以:
- 行顺序反转:用
collections.deque双端队列从后往前读(较复杂),或先读取所有行到列表(如果内存够)。 - 逐行处理:如果是每行内容反转,可以逐行读取、反转、写入临时文件,最后重命名(避免内存溢出)。
大文件逐行处理示例(每行内容反转):
# 大文件逐行处理,避免内存溢出
with open("big_file.txt", mode='r', encoding='utf-8') as f_in, \
open("big_file_reversed.txt", mode='w', encoding='utf-8') as f_out:
for line in f_in: # 逐行迭代,不一次性加载
# 反转每行
if line.endswith('\n'):
reversed_line = line.rstrip('\n')[::-1] + '\n'
else:
reversed_line = line[::-1]
f_out.write(reversed_line)
print("大文件逐行反转完成!")总结
- 字符串反转:优先用切片
s[::-1]。 - 列表反转:非原地用
lst[::-1],原地用lst.reverse()(注意返回none)。 - 元组反转:用
t[::-1]。 - 集合反转:无意义(无序)。
- 字典反转:键值互换用推导式,顺序反转转列表后反转。
- 文件反转:小文件用
readlines()反转行,大文件逐行处理。
到此这篇关于python中字符串和四大数据结构的反转操作指南的文章就介绍到这了,更多相关python反转操作内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论