现在有一段只由大小写英文字母组成的字符串,例如xyzABCXYZabc
。现在要把它的大小写字母翻转,变成XYZabcxyzABC
。
可能你会使用下面这种方案:
代码语言:javascript复制dst = ''
src = 'xyzABCXYZabc'
for letter in src:
if letter.isupper():
dst = letter.lower()
else:
dst = letter.upper()
运行效果如下图所示:
那么有没有办法,不用 if 条件判断就能翻转字母大小写呢?这个时候就要考虑字母的 Ascii 码了。
大写字符A-Z对应的 Ascii 码为 65~90,小写字母 a-z 对应的 Ascii 码为 97~122。
我们来看一下这些 Ascii 码对应的二进制值:
字母 | Ascii 码 | 二进制 |
---|---|---|
A | 65 | 1000001 |
a | 97 | 1100001 |
B | 66 | 1000010 |
b | 98 | 1100010 |
... | ... | ... |
Z | 90 | 1011010 |
z | 122 | 1111010 |
大家如果仔细观察,会发现:1000001
与 1100001
只有从右数第6位不一样。1000010
与1100010
只有从右数第6位不一样。...1011010
与1111010
只有从右数第6位不一样。
所以,如果想把大写 A 变成小写 a,只需要把1000001
右边第6位从0改成1即可。要把小写 b 变成大写 B,只需要把1100010从右数第6位换成0即可。
总结起来,就是,把从右数第6位,从1变成0就是小写,从0变成1,就是大写。其他位的数字完全不需要改变。
如果不使用 if 判断,怎么把1变成0,把0变成1呢?此时我们就可以使用二进制的异或操作:
代码语言:javascript复制1 xor 1 = 0
1 xor 0 = 1
0 xor 0 = 0
0 xor 1 = 1
异或运算,在两边相同时返回0,在两边不同时返回1.
所以,我们只需要把字母对应的 Ascii 码与100000做异或运算即可。
那么最终的代码变为:
代码语言:javascript复制dst = ''
src = 'xyzABCXYZabc'
for letter in src:
dst = chr(ord(letter) ^ 0b100000)
print(dst)
运行效果如下图所示:
上述代码中,ord
函数返回一个字符的 Ascii 码,chr
函数把 Ascii 码转成字符。