• Python核心技术与实战——三|字符串


    一.字符串基础

      Python的字符串支持单引号('')、双引号("")和三引号之中('''....'''和"""...""")三种写法这样就比较方便在字符串中嵌套带引号的字符串。

    a = "I'm a student"

      并且这三种表示方法是相同的内容

    >>> a = 'hello world'
    >>> b = "hello world"
    >>> c = '''hello world'''>>> a==b==c
    True

      三引号的作用主要是用于多行字符串或者是注释。

    '''
    这是一个字符串
    '''
    a = "I'm a student"

      字符串的转义字符

    转义字符描述
    (在行尾时) 续行符
    \ 反斜杠符号
    单引号
    双引号
    a 响铃
     退格(Backspace)
    e 转义
    00
    换行
    v 纵向制表符
    横向制表符
    回车
    f 换页
    oyy 八进制数yy代表的字符,例如:o12代表换行
    xyy 十进制数yy代表的字符,例如:x0a代表换行
    other 其它的字符以普通格式输出

    在字符串内,转义字符的长度也只占1个。

    >>> a = 'a
    bc	d'
    >>> len(a)
    6
    >>> print(a)
    a
    bc      d

    二.字符串的基本操作

      1.字符串可以像列表一样遍历、切片和索引。

    >>> name = 'jack'
    >>> name[0]
    'j'
    >>> name[0:2]
    'ja'
    >>> for i in name:
    ...     print(i)
    ...
    j
    a
    c
    k

    要注意的是在切片中,获取的元素索引是[index:index+2],则返回的实际元素是从index到index+1之间的元素。

    并且Python字符串中的元素是不可变的,不能改变其中的某个元素

    >>> name = 'jack'
    >>> name[0] = 'J'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment

    但是可以用下面的方法

    >>> name = 'J'+name[1:]
    >>> name = name.replace('j','J')

    主要是因为在Java等语言中,有可变的字符串类型(StringBuilder),每次添加、改变字符串需要O(1)的时间复杂度,程序运行效率能被大大提高。

    而在python中我们通常需要重新创建新的字符串,而每次改变字符串需要O(n)的时间复杂度,其中n为字符串的长度。

    这里的通常我着重标注了一下,因为使用加法操作符"+="就是一个例外

    >>> a = 'hello'
    >>> b = 'world'
    >>> a+=b
    >>> a
    'helloworld'    #a+=b  ——>a = a+b

    在这里举个例子,我们做一个字符串的循环累加

    s = ' '
    for n in range(0,1000000):
        s +=str(n)

    理论上,每次创建一个新的字符串就需要O(n)的时间复杂度,总的时间复杂度就是O(1)+O(2)+O(3)...+O(n)=O(n^2),对不对呢?

    这个结论在老版本的Python中是适用的,在Python2.5以后,每次处理字符串的拼接操作时(Str1+Str2),Python会先检测Str1还有没有其他的引用。如果没有的话就会尝试原地扩充字符串Buffer的大小,而不是重新分配一块内存来创建新的字符串并进行Copy。这样,在上述例子中的时间复杂度就成了O(n)了。所以在程序中如果使用"+="更加方便就尽可能的使用这个吧!

    2.字符串的拼接

      其实在上面一条有一部分讲的就是字符串的拼接,还有另外的一种方法——使用字符串的内置函数join()(str.join(iterable)这个用法),把每个元素按照要求的格式拼起来。

    >>> l = ['a','b','c']
    >>> s = '123'
    >>> s.join(l)
    'a123b123c'

    按照则个方式完成上面的案例

    l  = []
    for n in range(0,1000000):
        l.append(str(n))
    s = ' '.join(l)

    由于列表的append的时间复杂度时O(1),这里n次for循环就是O(n),

    3.字符串的分割

    string.split(separator)      #按照要求分割成列表
    string.strip(str)            #去除首尾的str字符
    string.lstrip(str)           #去除开头的str字符
    strint.rstrip(str)           #去除结尾的str字符

    我们常常用strip来去除读出的数据前的空格啥的

     三.字符串的格式化

      我们通常在程序的输出、logging等场景会使用一个字符串作为模板,模板中留有格式符来为后续实际值预留位置。就像这样使用

    >>> name = 'jack'
    >>> id = 11
    >>> print('{} id is {}'.format(name,id))
    jack id is 11

    在这里,大括号{}就是与预留符,为后面的name和id预留了在字符串里的位置。其实和这样的使用方法时一样的

    >>> print('%s id is %d'%(name,id))

    只不过string.format()是最新的字符串格式函数与规范,也是官方文档推荐的规范

    四.思考题

      在2.5+版本的Python中,下面两个方法哪个是更好的呢?

    #方式A
    s = ''
    for n in range(0,100000):
        s+=str(n)
        
    #方式B
    l = []
    for n in range(0,100000):
        l.append(str(n))
    s = ' '.join(l)

      解答:其实如果字符串拼接的次数较少,比如range(100),那么第一种方法更优。但是如果拼接的次数较多,比如range(1000000),方法B稍快一些,虽然它会遍历两次,但join的速度是很快的,列表append和join的开销比+=要小一些。可以加上时间验证一下

    import time
    n = 100
    #方式A
    time_1 = time.perf_counter()
    s = ''
    for n in range(0,n):
        s+=str(n)
    time_2 = time.perf_counter()
    #方式B
    l = []
    for n in range(0,n):
        l.append(str(n))
    s = ' '.join(l)
    time_3 = time.perf_counter()
    print(time_2-time_1,time_3-time_2)
    验证

    当n=100时,两个时间都差不多,但n=1000000时,时间就成了

    方式A:2.7928060934153014
    方式B:0.41785306529077815

    差距是不是一下就明显了!

  • 相关阅读:
    Hibernate
    Mysql
    JavaWeb
    Springboot
    spring MVC
    spring
    mybatis学习
    ftp客户端封装
    win10子系统 wsl开机启动ssh服务
    eclipse 终于官方支持代码模糊提示了
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/11148838.html
Copyright © 2020-2023  润新知