python之字符串逆序

1.贴题

题目来自PythonTip
字符串逆序


给你一个字符串 a, 请你输出逆序之后的a。

例如:a=‘xydz’

则输出:zdyx


2.说明

思路基本分为两种,
一是编写循环,每次取字符串的一个字符,从后往前取,可以直接输出,也可以添加到新字符串最后一起输出。
二是利用切片,一行代码完成。

3.参考代码

1.循环方法

m = list(a)
for i in range(len(a)-1,-1,-1):
    print(m[i],end = '')

2.切片方法

print(a[::-1])

4.其他写法

1.先把字符串转化为列表,然后倒序,再循环输出

L = list(a)
L.reverse()

for letter in L:
    print(letter,end = '')

2.创建新的空字符串,循环将每一个字符添加到现有字符串的最前面,最后输出

A = ''
for i in a:
    A = i + A
print(A)

3.同样一行搞定的其他写法之一:先反转再连接

print(''.join(reversed(list(a))))

4.之二:先逆向排序再连接(如果题目给出的字符串不是有序的,此代码会出错)

print(''.join(sorted(a,reverse=True)))

5.注意点和坑

  1. 因为PythonTip只支持python2,所以使用print函数里面如果带了sep或者end的参数会报错,解决方法是在最前面加上
    from __future__ import print_function
  2. a = '12345'
    a = a[::-1]
    print(a)

    以为这个会错,结果执行了一下发现是对的。因为虽然字符串是不可变的,不能改变某一个字符,但是重新赋值是可以的。

6.继续探究

1.关于切片的逆序输出
先考虑以下代码的输出是什么

a = [1,2,3,4,5]
print(a[::-1])
print(a[-1::-1])
print(a[-1:-5:-1])
print(a[-1:-6:-1])

考虑好了看答案

[5, 4, 3, 2, 1]
[5, 4, 3, 2, 1]
[5, 4, 3, 2]
[5, 4, 3, 2, 1]

所以如果要进行逆序输出可以有很多种写法,上面的四种写法中除了第三种都可以正确输出。
原因其实是python有两种索引方法,一种是0开始的正数索引,另一种是-1开始的复数索引,只要采用其中任何一套索引都可以完成切片行为。

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

来自python3的官方说明文档


2018/4/25追加
追加测试代码

a = "python"

print(a[::-1])
print(a[-1::-1])
print(a[-1:-5:-1])
print(a[-1:-6:-1])

猜猜输出结果是什么

nohtyp
nohtyp
noht
nohty

然后再看一下官方文档给的那个图

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

然后就发现不对了????负数索引对不上啊????
再增加几行代码

print(a[-1:-7:-1])
print(a[-7:-1:1])
print(a[-1:-7:-2])
print(a[-5:-1:2])

输出为

nohtyp
pytho
nhy
yh

到这里你就知道问题在哪里了。
上面的图是针对步长为正数时候的,而当步长为负数的时候,正确的索引图应该如下

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+                 #步长为负数
 0   1   2   3   4   5   6
-7  -6  -5  -4  -3  -2  -1

所以还是记住“顾头不顾尾,正向0开始,逆向-1开始”这个口诀,假装索引是与字符对齐而不是与边界对齐的吧。


2.关于切片的拓展应用
在上面我们已经知道了切片可以用来处理字符串和列表,那么还有哪些地方可以用到切片呢?
为了探究这个问题,我写了以下的测试代码

a = "abcd"
b = [1,"a",(1,2),[3,4],{"aa":1,"bb":2},a]
c = ("li",1,2)
d = {"cc":1,"dd":2}
e = {"a","abc","abcd"}
f = 123456

print(a[::-1])
print(b[::-1])
print(c[::-1])
print(d[::-1])
print(e[::-1])
print(f[::-1])
  • a是字符串
  • b是混合类型的列表
  • c是元组
  • d是字典
  • e是集合
  • f是数字

猜猜有哪一些是可以切片的呢?

答案

dcba #字符串逆序
['abcd', {'aa': 1, 'bb': 2}, [3, 4], (1, 2), 'a', 1] #列表逆序
(2, 1, 'li') #元组逆序

Traceback (most recent call last):
  File "jdoodle.py", line 10, in <module>
    print(d[::-1])
TypeError: unhashable type: 'slice' #该数据类型不能被hash
Command exited with non-zero status 1

Traceback (most recent call last):
  File "jdoodle.py", line 11, in <module>
    print(e[::-1])
TypeError: 'set' object is not subscriptable #集合不能用下标访问
Command exited with non-zero status 1

Traceback (most recent call last):
  File "jdoodle.py", line 13, in <module>
    print(f[::-1])
TypeError: 'int' object is not subscriptable #数字不能用下标访问
Command exited with non-zero status 1

总结如下

  • 字符串,列表,元组可以切片
  • 字典可以用下标访问,但是要使用key而不是数字访问所以不能切片
  • 集合和数字不能用下标访问,所以不能切片

拓展知识
1.有大神做出了有序可以切片的字典,看代码

# Slicing an OrderedDict
>>> d = OrderedDict([(7, 0), (6, 1), (5, 2), (4, 3)])
>>> d[::-1]
OrderedDict([(4, 3), (5, 2), (6, 1), (7, 0)])
>>> d[1:3]
OrderedDict([(6, 1), (5, 2)])
>>> type(d[1:3])
<class '__main__.OrderedDict'>

可以切片的字典

2.python六种基本数据类型比较

特征 字符串 列表 元组 字典 集合
是否可变
是否有序
是否可重复 key不可,value可
是否有下标 使用key
是否可哈希

总结

猜你喜欢

转载自blog.csdn.net/weixin_41980474/article/details/80065652