• 深入理解Python字符串的用法


    1. 拆分字符串

    在字符串的几种拼接方法中,join() 方法可以将列表中的字符串元素,拼接成一个长的字符串,与此相反,split() 方法可以将长字符串拆分成一个列表。前面已说过,字符串是不可变序列,所以字符串拆分过程是在拷贝的字符串上进行,并不会改变原有字符串。

    split() 方法可接收两个参数,第一个参数是分隔符,即用来分隔字符串的字符,默认是所有的空字符,包括空格、换行( )、制表符( )等。拆分过程会消耗分隔符,所以拆分结果中不包含分隔符。

    s = 'Hello world'
    
    l = '''Hi there , my name is Python猫
    
    Do you like me ?
    
    '''
    

      

    # 不传参数时,默认分隔符为所有空字符

    s.split() >>> ['Hello', 'world']
    
    s.split(' ') >>> ['Hello', 'world']
    
    s.split(' ') >>> ['Hello world'] # 不存在两个空格符
    
    s.split('world') >>> ['Hello', '']
    

      

    # 空字符包括空格、多个空格、换行符等

    l.split() >>> ['Hi', 'there', ',', 'my', 'name', 'is', 'Python猫', 'Do', 'you', 'like', 'me', '?']
    

      

    split() 方法的第二个参数是一个数字,默认是缺省,缺省时全分隔,也可以用 maxsplit 来指定拆分次数。

    
    

    # 按位置传参

    l.split(' ',3)
    
    >>> ['Hi', 'there', ',', 'my name is Python 猫
    
    Do you like me ?
    
    ']

    # 指定传参

    l.split(maxsplit=3)
    
    >>> ['Hi', 'there', ',', 'my name is Python 猫
    
    Do you like me ?
    
    ']
    

      

    # 错误用法

    l.split(3)
    
    ---------------
    
    TypeError Traceback (most recent call last)
    
    <ipython-input-42-6c16d1a50bca> in <module>()
    
    ----> 1 l.split(3)
    
    TypeError: must be str or None, not int
    

      

    split() 方法是从左往右遍历,与之相对,rsplit() 方法是从右往左遍历,比较少用,但是会有奇效。

    拆分字符串还有一种方法,即 splitlines() ,这个方法会按行拆分字符串,它接收一个参数 True 或 False ,分别决定换行符是否会被保留,默认值 False ,即不保留换行符。

    
    

    # 默认不保留换行符

    'ab c
    
    kl
    
    de fg
    
    '.splitlines()
    
    >>> ['ab c', '', 'de fg', 'kl']
    
    
    
    'ab c
    
    kl
    
    de fg
    
    '.splitlines(True)
    
    >>> ['ab c
    
    ', '
    
    ', 'de fg
    
    ', 'kl
    
    ']
    

      

    2. 替换字符串

    替换字符串包括如下场景:大小写替换、特定符号替换、自定义片段替换……

    再次说明,字符串是不可变对象,以下操作并不会改变原有字符串。

    196502ad081c45ca5427dd588705b752d9337de7

    以上这些方法都很明了,使用也简单,建议你亲自试验一下。这里只说说 strip() 方法,它比较常用,可以去除字符串前后的空格,不仅如此,它还可以删除首末位置的指定的字符。

    
    

    s = '******Hello world******'

    s.strip('*') >>> 'Hello world'

    3. 查找字符串

    查找字符串中是否包含某些内容,这是挺常用的操作。Python 中有多种实现方式,例如内置的 find() 方法,但是这个方法并不常用,因为它仅仅告诉你所查找内容的索引位置,而在通常情况下,这个位置并不是我们的目的。

    find() 方法与 index() 方法的效果一样,它们的最大的区别只在于,找不到内容时的返回值不同,一个返回 -1,一个抛出异常 :

    
    

    s = 'Hello world'

     

    s.find('cat'>>> -1


    s.index('cat')

    >>> ValueError Traceback (most recent call last)

    <ipython-input-55-442007c50b6f> in <module>()

    ----> 1 s.index('cat')


    ValueError: substring not found

    以上两个方法,只能用来满足最简单的查找需求。在实战中,我们常常要查找特定模式的内容,例如某种格式的日期字符串,这就得借助更强大的查找工具了。正则表达式和 re 模块就是这样的工具,正则表达式用来定制匹配规则,re 模块则提供了 match() 、find() 及 findall() 等方法,它们组合起来,可以实现复杂的查找功能。限于篇幅,今后再对这两大工具做详细介绍,这里有一个简单的例子:

    
    

    import re

    datepat = re.compile(r'd+/d+/d+')

    text = 'Today is 11/21/2018. Tomorrow is 11/22/2018.'

    datepat.findall(text)

    >>> ['11/21/2018', '11/22/2018']

    4. 字符判断

    判断字符串是否(只)包含某些字符内容,这类使用场景也很常见,例如在网站注册时,要求用户名只能包含英文字母和数字,那么,当校验输入内容时,就需要判断它是否只包含这些字符。其它常用的判断操作,详列如下:

    30b44f25614d18c0d4050f7135cd7ee5518dbdc4

    5. 字符串不可以做的事

    上文内容都是 Python 字符串特有的操作方法,相信读完之后,你更清楚知道 Python 能够做什么了。

    但是,这还不足以回答本文标题的问题——你真的知道 Python 的字符串怎么用吗?这些特有的操作方法,再加上之前文章提到的序列共有的操作、字符串读写文件、字符串打印、字符串Intern机制等等内容,才差不多能够回答这个问题。

    尽管如此,为了体现严谨性,我试着再聊聊“Python 字符串不可以做的事”,从相反的维度来补充回答这个问题。下面是开拓思维,进行头脑风暴的时刻:

    (1)受限的序列

    与典型的序列类型相比,字符串不具备列表的如下操作:append()、clear()、copy()、insert()、pop()、remove(),等等。这是为什么呢?

    有几个很好理解,即append()、insert()、pop() 和 remove(),它们都是对单个元素的操作,但是,字符串中的单个元素就是单个字符,通常没有任何意义,我们也不会频繁对其做增删操作,所以,字符串没有这几个方法也算合理。

    列表的 clear() 方法会清空列表,用来节省内存空间,效果等于anylist[:] = [],但是,奇怪的是,Python 并不支持清空/删除操作。

    首先,字符串没有 clear() 方法,其次,它是不可变对象,不支持这种赋值操作anystr[:] = '',也不支持del anystr[:]操作:

    
    

    s = 'Hello world'

     

    s[:] = ''

    >>> 报错:TypeError: 'str' object does not support item assignment


    del s[:]

    >>> 报错:TypeError: 'str' object does not support item deletion

    当然,你也别想通过del s来删除字符串,因为变量名 s 只是字符串对象的引用(挖坑,以后写写这个话题),只是一个标签,删除标签并不会直接导致对象实体的消亡。

    如此看来,想要手动清空/删除 Python 字符串,似乎是无解。

    最后还有一个 copy() 方法,这就是拷贝嘛,可是字符串也没有这个方法。为什么呢?难道拷贝字符串的场景不多么?在这点上,我也没想出个所以然来,搁置疑问。

    通过以上几个常用列表操作的比较,我们可以看出字符串这种序列是挺受限的。列表可以看成多节车厢链接成的火车,而字符串感觉就只像多个座椅联排成的长车厢,真是同源不同相啊。

    (2)比就比,谁怕谁

    接下来,又到了 Python 字符串与 Java 字符串 PK 的时刻。在上一篇文章《你真的了解Python的字符串吗?》中,它们已经在对象定义的角度切磋了两回合,胜利的天平倒向了 Python,这次看看会比出个啥结果吧。

    Java 中有比较字符串的方法,即 compareTo() 方法与 equals() 方法,前一个方法逐一比较两个字符串的字符编码,返回一个整型的差值,后一个方法在整体上比较两个字符串的内容是否相等。

    Python 字符串没有这两个单独的方法,但要实现类似的功能却很简便。 先看例子:

    
    

    myName = "Python猫"

    cmpName = "world"

    newName = myName

     

    # 直接用比较符号进行compare

    myName > cmpName

    >>> False

    myName == newName

    >>> True

    cmpName != newName

    >>> True


    # 比较是否同一对象

    myName is cmpName

    >>> False

    myName is newName

    >>> True

    上例中,如果把赋值的字符串换成列表或者其它对象,这些比较操作也是可以进行的。也就是说,作比较的能力是 Python 公民们的一项基本能力,并不会因为你是字符串就给你设限,或者给你开特权。

    与此类似,Python 公民们自带求自身长度的能力,len() 方法是内置方法,可以直接传入任意序列参数,求解长度。Java 中则要求不同的序列对象,只能调用各自的 length() 方法。说个形象的比喻,Python 中共用一把秤,三教九流之辈都能拿它称重,而Java 中有多把秤,你称你的,我称我的,大家“井水不犯河水”。

    Python 中曾经有 cmp() 方法和__cmp__()魔术方法,但官方嫌弃它们鸡肋,所以在Python 3 中移除掉了。虽然在 operator 模块中还为它留下了一脉香火,但保不定哪天就会彻底废弃。

    
    

    import operator

    operator.eq('hello', 'name')

    >>> False

    operator.eq('hello', 'hello')

    >>> True

    operator.gt('hello', 'name')

    >>> False

    operator.lt('hello', 'name')

    >>> True

    (3)墙上的门

    在 Java 中,字符串还有一个强大的 valueOf() 方法,它可以接收多种类型的参数,如boolean、char、char数组、double、float、int等等,然后返回这些参数的字符串类型。 例如,要把 int 转为字符串,可以用 String.valueOf(anynum) 。

    Python 字符串依然没有这个单独的方法,但要实现相同的功能却很简便。对Python来说,不同的数据类型转换成字符串,那是小菜一碟,例如:

    
    

    str(123) >>> '123'

    str(True) >>> 'True'

    str(1.22) >>> '1.22'

    str([1,2]) >>> '[1, 2]'

    str({'name':'python', 'sex':'male'})

    >>> "{'name': 'python', 'sex': 'male'}"

    而从字符串转换为其它类型,也不难,例如,int('123') 即可由字符串'123' 得到数字 123。对比 Java,这个操作要写成 Integer.parseInt('123')

    在Java 的不同数据类型之间,那道分隔之墙矗立得很高,仿佛需要借助一座更高的吊桥才能沟通两边,而在灵活的 Python 里,你可以很方便地打开墙上的那扇门,来往穿越。

    小结一下,跟 Java 相比,Python 字符串确实没有几项方法,但是事出有因,它们的天赋能力可不弱,所有这些操作都能简明地实现。一方面,Python 字符串做不到某些事,但是另一方面,Python 可以出色地做成这些事,孰优孰劣,高下立判。

    6. 总结

    写文章贵在善始善终,现在给大家总结一下:本文主要介绍 Python 字符串特有的操作方法,比如它的拼接、拆分、替换、查找及字符判断等使用方法,从正向回答,Python 字符串能做什么?最后,我们还从反向来回答了 Python 字符串不能做什么?有些不能做,实际上是 不为,是为了在其它地方更好地作为,归根到底,应该有的功能,Python 字符串全都有了。

    本文中依然将 Python 与 Java 做了比较,有几项小小的差异,背后反映的其实是,两套语言系统在世界观上的差异。古人云,以铜为镜,可以正衣冠。那么,在编程语言的世界里,以另一种语言为镜,也更能看清这种语言的面貌。希望这种跨语言的思维碰撞,能为你擦出智慧的火花。

  • 相关阅读:
    信息检索重点关键字
    信息检索重点关键字
    信息检索重点关键字
    信息检索关键词部分
    信息检索关键词部分
    信息检索关键词部分
    输入五个国家的名称按字母顺序排列输出
    把一个整数按大小顺序插入已排好序的数组中
    快放假了
    清炒苦瓜
  • 原文地址:https://www.cnblogs.com/daniumiqi/p/12120367.html
Copyright © 2020-2023  润新知