一文带你了解Python中的字符串是什么

在《 详解Python拼接字符串的七种方式 》这篇文章里,我提到过,字符串是程序员离不开的事情。后来,我看到了一个英文版本的说法:

There are few guarantees in life: death, taxes, and programmers needing to deal with strings.
它竟然把程序员处理字符串跟死亡大事并列了,可见这是多么命中注定……

回头看其它文章,我发现这种说法得到了佐证,因为我在无意中已零零碎碎地提及了字符串的很多方面,例如:字符串读写文件、字符串打印、字符串不可变性、字符串Intern机制、字符串拼接、 是否会取消字符串 ,等等。而这些,还只能算字符串面目的冰山一角。

既然如此,那干脆再单独写写Python的字符串吧。这篇内容可能会很基(li)础(lun),并不是什么“骚操作”或“冷知识”,权当是一份温故而求知新的笔记。

1 Python字符串是什么?

根据维基百科定义:字符串是由零个或多个字符组成的有限序列。而在Python 3中,它有着更明确的意思: 字符串是由Unicode码点组成的不可变序列 (Strings are immutable sequences of Unicode code points.)

字符串是一种序列,这意味着它具备序列类型都支持的操作:

# 以下的s、t皆表示序列,x表示元素
x in s # 若s包含x,返回True,否则返回False
x not in s # 若s包含x,返回False,否则返回True
s + t # 连接两个序列
s * n # s复制n次
s[i] # s的索引第i项
s[i:j] # s切片从第i项到第j-1项
s[i:j:k] # s切片从第i项到第j-1项,间隔为k
len(s) # s的长度
min(s) # s的最小元素
max(s) # s的最大元素
s.index(x) # x的索引位置
s.count(x) # s中出现x的总次数

字符串序列还具备一些特有的操作,限于篇幅,按下不表。预告一下,下一篇《 你真的知道Python的字符串怎么用吗? 》将会展开介绍,敬请期待……

字符串序列是一种不可变序列,这意味着它不能像可变序列一样,进行就地修改。例如,在字符串“Python”的基础上拼接“Cat”,得到字符串“PythonCat”,新的字符串是一个独立的存在,它与基础字符串“Python”并没有关联关系。

basename = "Python"
myname = basename + "Cat"
id(basename) == id(myname) >>> False
# 作为对比,列表能就地修改
baselist = ["Python"]
baselist.append("Cat")
print(baselist) >>> ['Python', 'Cat']

字符串这种序列与其它序列(如列表、元组)的不同之处在于,它的“元素”限定了只能是Unicode码点。Unicode码点是什么呢?简单理解,就是用Unicode编码的字符。那字符是什么呢? 字符 是人类书写系统的各类符号,例如阿拉伯数字、拉丁字母、中文、日文、藏文、标点符号、控制符号(换行符、制表符等)、其它特殊符号(@#¥%$*等等)。那Unicode编码又是什么呢?Unicode别名是万国码、国际码,它是一种适用性最广的、将书写字符编码为计算机数字的标准。

总所周知,在最底层的计算机硬件世界里,只有0和1。那么,怎么用这个二进制数字,来表示人类的文化性的字符呢?这些字符数量庞大,而且还在日益增长与变化,什么样的编码方案才是最靠谱的呢?

历史上,人类创造了多种多样的字符编码标准,例如ASCII(1963年)编码,以西欧语言的字符为主,它的缺点是只能编码128个字符;例如GB2312(1981年),这是中国推出的编码标准,在兼容ASCII标准的基础上,还加入了对日文、俄文等字符的编码,但缺点仍是编码范围有限,无法表示古汉语、繁体字及更多书写系统的字符。

Unicode编码标准于1991年推出,至今迭代到了第11版,已经能够编码146个书写系统的130000个字符,可谓是无所不包,真不愧是“国际码”。Unicode编码其实是一个二进制字符集,它建立了从书写字符映射成唯一的数字字符的关系,但是,由于各系统平台对字符的理解差异,以及出于节省空间的考虑,Unicode编码还需要再做一次转换,转换后的新的二进制数字才能作为 实际存储及网络传输时的编码 。

这种转换方式被称为 Unicode转换格式 (Unicode Transformation Format,简称为UTF),它又细分为UTF-8、UTF-16、UTF-32等等方式。我们最常用的是UTF-8。为什么UTF-8最常用呢?因为它是可变长度的编码方案,针对不同的字符使用不同的字节数来编码,例如编码英文字母时,只需要一个字节(8个比特),而编码较复杂的汉字时,就会用到三个字节(24个比特)。

二进制的编码串可以说是给机器阅读的,为了方便,我们通常会将其转化为十六进制,例如“中”字的Unicode编码可以表示成 0x4e2d ,其UTF-8编码可以表示为 0xe4b8ad ,'0x'用于开头表示十六进制,这样就简洁多了。不过,UTF-8编码的结果会被表示成以字节为单位的形式,例如“中”字用UTF-8编码后的字节形式是 \xe4\xb8\xad 。

Python中为了区分Unicode编码与字节码,分别在开头加“u”和“b”以示区分。在Python 3中,因为Unicode成了默认编码格式,所以“u”被省略掉了。

# 字符转Unicode编码
# Python3中,开头的u被省略,b不可省略
hex(ord('中')) >>> '0x4e2d'
hex(ord('A')) >>> '0x41'
# 字符转UTF-8编码(encode)
'中'.encode('utf-8') >>> b'\xe4\xb8\xad'
'A'.encode('utf-8') >>> b'A'
# Unicode编码还原成字符
chr(0x4e2d) >>> '中'
chr(0x41) >>> 'A'
# UTF-8编码还原成字符(decode)
b'\xe4\xb8\xad'.decode('utf-8') >>> '中'
b'A'.decode('utf-8') >>> 'A'

总结一下,Python 3 中的字符串是由Unicode码点组成的不可变序列,也即是,由采用Unicode标准编码的字符组成的不可变序列。Unicode编码将书写系统的字符映射成了计算机二进制数字,为了方便,通常显示为十六进制;在运算内存中,字符以Unicode编码呈现,当写入磁盘或用于网络传输时,一般采用UTF-8方式编码。

在Python 2中,因为历史包袱,即Python先于Unicode编码而诞生,所以其编码问题是个大难题。幸好抛弃Python 2已成大势所趋,所以我就不再对此做介绍或比对了。

2 Python字符串 VS Java字符串

虽然不提纵向版本间的差异,但是,我想将Python字符串与其它编程语言做一个横向对比。我觉得这会是挺好玩的事。通过跨语言的比较,也许我们能加深对一个事物(字符串)的理解,还可能受到启发,得到对“编程语言”及“编程哲学”的领悟。

由于本人才疏学浅,本文就只对两点皮毛特性作说明,欢迎读者斧正和补充。

(1)字符串的定义方式

Python的字符串是内置类型,所以使用起来很方便,有如下三种定义方式:

str_0 = '''Python字符串可以写在用三引号对内,表示多行字符串。
还可以写在单引号对内,
当然还可以写在双引号对内。
'''
str_1 = 'Python猫是一只猫'
str_2 = "Python猫是一个微信公众号"

Java的字符串不是内置类型,它属于对象,需要通过String类来创建。不过,正因为字符串太常用,所以Java特意预定义了一个字符串类String,使得程序员也可以像这样来定义: String name = "Python猫"; ,而不必这样写: String name = new String("Python猫"); 。

Java的字符串只能写在双引号内,不具备Python中单双引号混用的灵活。至于三引号的多行字符串表示法,Java程序员表示羡慕得要死,那种痛苦,受过折磨的人最懂。写出来让Python程序员开心一下:

String s = "Java 的多行字符串很麻烦,\n"
  + "既要使用换行符,\n"
  + "还需要使用加号拼接";

为什么Java不支持多行字符串、什么时候支持多行字符串?此类问题在Python程序员眼里,可能很费解,但它绝对能排进“Java程序员最希望能实现的特性”的前列。好不容易,官方有计划在Java 11 实现,但今年9月发布的Java 11 仍是没有,现在改计划到Java 12 了。

(2)单个字符与字符序列

Java中其实也有单引号的使用,用在char类型上,例如 char c = 'A'; 。char是一种内置类型,表示单个用Unicode编码的字符。Python中没有char类型,字符串类型通吃一切。

前面说到,Python的字符串是一种字符序列,而Java的字符串并不是一种序列,要表示相近的概念的话,就得用到 字符数组 或者 字符串数组 ,例如:

char[] a = { 'a', 'b', 'c'};
String[] str = new String[]{"1","2","3"};

字符数组和字符串数组是一种序列,但并不是字符串,它们之间如果要相互转换,还是挺麻烦的。另外,说是序列,但Java的序列操作绝对无法跟Python相比,别的不说,就上面提及的几个基础操作,试问Java能否实现、实现起来要花费多大力气?

最后来个Ending,关于“Python字符串到底是什么”就说到这啦,希望对你有所帮助。下次,我再跟大家说说“Python字符串到底怎么用”,敬请期待。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Python不使用int()函数把字符串转换为数字的方法

    不使用int()函数的情况下把字符串转换为数字,如把字符串"12345"转换为数字12345. 方法一:利用str函数 既然不能用int函数,那我们就反其道而行,用str函数找出每一位字符表示的数字大写. def atoi(s): s = s[::-1] num = 0 for i, v in enumerate(s): for j in range(0, 10): if v == str(j): num += j * (10 ** i) return num 方法二:利用ord函数

  • Python常用字符串替换函数strip、replace及sub用法示例

    本文实例讲述了Python常用字符串替换函数strip.replace及sub用法.分享给大家供大家参考,具体如下: 今天在做一道今年秋季招聘题目的时候遇上了一个替换的问题,题目看起来好长好复杂啊,真的,一时间,我看了好几遍也没看懂,其实实质很简单,就是需要把给定的一个字符串里面的指定字符替换成一些指定的内容就行了,这样首选当然是字典了,没有之一,题目很简单就不写出来了,在这里花了一点时间专门总结了一下字符串的替换的几个常用的函数,希望也能帮到有需要的人,自己也是当做一个学习的记录,好了,在这里

  • python中字符串的操作方法大全

    前言 python中字符串对象提供了很多方法来操作字符串,功能相当丰富. print(dir(str)) [..........'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'i

  • Python使用re模块正则提取字符串中括号内的内容示例

    本文实例讲述了Python使用re模块正则提取字符串中括号内的内容操作.分享给大家供大家参考,具体如下: 直接上代码吧: # -*- coding:utf-8 -*- #! python2 import re string = 'abe(ac)ad)' p1 = re.compile(r'[(](.*?)[)]', re.S) #最小匹配 p2 = re.compile(r'[(](.*)[)]', re.S) #贪婪匹配 print(re.findall(p1, string)) print(

  • Python判断字符串是否为字母或者数字(浮点数)的多种方法

    str为字符串s为字符串 str.isalnum() 所有字符都是数字或者字母 str.isalpha() 所有字符都是字母 str.isdigit() 所有字符都是数字 str.isspace() 所有字符都是空白字符.t.n.r 检查字符串是数字/浮点数方法 float部分 >> float('Nan') nan >> float('Nan') nan >> float('nan') nan >> float('INF') inf >> fl

  • python删除字符串中指定字符的方法

    最近开始学机器学习,学习分析垃圾邮件,其中有一部分是要求去除一段字符中的标点符号,查了一下,网上的大多很复杂例如这样 import re temp = "司法局让我和户 1 5. 8 0. !!?? 客户维护户外" temp = temp.decode("utf8") string = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+--!,.?.~@#¥%--&*()]+".decode("ut

  • python 查找文件名包含指定字符串的方法

    编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出绝对路径. import os class SearchFile(object): def __init__(self,path='.'): self._path=path self.abspath=os.path.abspath(self._path) # 默认当前目录 def findfile(self,keyword,root): filelist=[] for root,dirs,files in

  • Python 十六进制整数与ASCii编码字符串相互转换方法

    在使用Pyserial与STM32进行通讯时,遇到了需要将十六进制整数以Ascii码编码的字符串进行发送并且将接收到的Ascii码编码的字符串转换成十六进制整型的问题.查阅网上的资料后,均没有符合要求的,遂结合各家之长,用了以下方法. 环境 Python2.7 + Binascii模块 十六进制整数转ASCii编码字符串 # -*- coding: utf-8 -*- import binascii #16进制整数转ASCii编码字符串 a = 0x665554 b = hex(a) #转换成相

  • 一文带你了解Python中的字符串是什么

    在< 详解Python拼接字符串的七种方式 >这篇文章里,我提到过,字符串是程序员离不开的事情.后来,我看到了一个英文版本的说法: There are few guarantees in life: death, taxes, and programmers needing to deal with strings. 它竟然把程序员处理字符串跟死亡大事并列了,可见这是多么命中注定-- 回头看其它文章,我发现这种说法得到了佐证,因为我在无意中已零零碎碎地提及了字符串的很多方面,例如:字符串读写文

  • 一文带你了解Python中的双下方法

    目录 前言 1. init方法 2. 运算符的双下方法 2.1 比较运算符 2.2 算术运算符 2.3 反向算术运算符 2.4 增量赋值运算符 2.4 位运算符 3.字符串表示 4.数值转换 5.集合相关的双下方法 6.迭代相关的双下方法 7.类相关的双下方法 7.1 实例的创建和销毁 7.2 属性管理 7.3 属性描述符 8.总结 前言 大家在写 Python 代码的时候有没有这样的疑问. 为什么数学中的+号,在字符串运算中却变成拼接功能,如'ab' + 'cd'结果为abcd:而*号变成了重

  • 一文带你解决Python中的所有报错

    目录 前言 Python安装 HTTPSConnectionPool(host=‘files.pythonhosted.org‘, port=443): Read timed out解决 xlrd.biffh.XLRDError: Excel xlsx file; not supported解决 Fatal error in launcher: Unable to create process using解决 报错Non-zero exit code (2)解决 [notice] A new r

  • 一文带你了解Python 四种常见基础爬虫方法介绍

    一.Urllib方法 Urllib是python内置的HTTP请求库 import urllib.request #1.定位抓取的url url='http://www.baidu.com/' #2.向目标url发送请求 response=urllib.request.urlopen(url) #3.读取数据 data=response.read() # print(data) #打印出来的数据有ASCII码 print(data.decode('utf-8')) #decode将相应编码格式的

  • 一文带你解密Python可迭代对象的排序问题

    假设有一个可迭代对象,现在想要对它内部的元素进行排序,我们一般会使用内置函数 sorted,举个例子: data = (3, 4, 1, 2, 5) print(     sorted(data) )  # [1, 2, 3, 4, 5] data = (3.14, 2, 1.75) print(     sorted(data) )  # [1.75, 2, 3.14] data = ["satori", "koishi", "marisa"]

  • 一文带你了解Python列表生成式应用的八重境界

    目录 1. 引言 2. Level1: 基础用法 3. Level2: 加入条件语句 4. Level3: 加入 enumerate() 5. Level4: 加入 zip() 6. Level5: 加入三目运算符 7. Level6: 嵌套循环 8. Level7: 嵌套列表生成式 9. Level8: 合并上述所有技巧 10. 应用栗子 11. 总结 1. 引言 在Python中有非常多且好用的技巧,其中使用最多的是列表生成式,往往可以将复杂的逻辑用简单的语言来实现,本文重点介绍列表生成式应

  • 10个示例带你掌握python中的元组

    数据结构是任何编程语言的关键部分.为了创建强大而性能良好的产品,必须非常了解数据结构. 在本文中,我们将研究Python编程语言的重要数据结构,元组. 元组是用逗号分隔并括在括号中值的集合.与列表不同,元组的元素是不可变的.不变性可以视为元组的识别特征. 我将通过示例解释元组的功能和对其的操作. 一.创建元组 元组由括号中的值组成,并用逗号分隔开 a=(3,4) print (a) print (type(a)) # (3, 4) # <class 'tuple'> 元组可以存储不同数据类型的

  • 一文秒懂Python中的字符串

    摘要:本文将告诉您Python中的字符串是什么,并向您简要介绍有关该概念的所有知识. 因此,让我们开始吧. 什么是Python中的字符串? 我们许多熟悉C,C ++等编程语言的人都会得到诸如"字符串是字符的集合或字符数组"的答案. 在Python中也是如此,我们说的是String数据类型的相同定义.字符串是序列字符的数组,并写在单引号,双引号或三引号内.另外,Python没有字符数据类型,因此当我们编写" a"时,它将被视为长度为1的字符串. 继续本文,了解什么是P

  • 一分钟带你掌握Python中pip的安装与使用方法

    目录 一.简单介绍 二.下载安装 三.最常用命令 1.显示版本和路径 2.获取帮助 3.升级 pip 4.安装包 5.升级包 6.卸载包 7.搜索包 8.显示安装包信息 9.列出已安装的包 10.查看指定包的详细信息 一.简单介绍 pip 是 Python 包管理工具,该工具提供了对Python 包的查找.下载.安装和卸载的功能,现在大家用到的所有包不是自带的就是通过pip安装的.Python 2.7.9 + 或 Python 3.4+ 以上版本都自带 pip 工具.给出pip官网链接:pip官

  • 一文带你理解 Vue 中的生命周期

    目录 1.beforeCreate & created 2.beforeMount & mounted 3.beforeUpdate & updated 4.beforeDestroy & destroyed 5.activated & deactivated 前言: 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如需要设置数据监听.编译模板.挂载实例到 DOM.在数据变化时更新 DOM 等.同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户

随机推荐