Python中的深浅拷贝、列表和元组和字符串类、排序算法以及应用

1. 说明浅拷贝与深拷贝的区别

在Python中,赋值语句并不会拷贝对象,赋值语句只是在变量名与对象之间建立一个绑定关系。当我们使用=号赋值操作符的时候,只是创建了一个新的变量名,并且将该变量名与相关的对象绑定在一起。

在Python中有两种创建拷贝的方式,分别如下所示:

  • Deep copy——深拷贝
  • Shallow copy——浅拷贝

为了揭示这两者之间的区别,使用copy模块做如下示例。

# importing copy module
import copy
# initializing list 1 
li1 = [1, 2, [3, 5], 4]
# using copy for shallow copy 
li2 = copy.copy(li1)
# using deepcopy for deepcopy
li3 = copy.deepcopy(li1) 

在上面的代码中,copy.copy()方法返回列表对象的浅拷贝;而copy.deepcopy()方法返回列表对象的深拷贝。

1.1. Deep copy——深拷贝

在这里插入图片描述深拷贝是递归进行的,也就是说这个过程会先构建一个集合类型的对象,比如列表对象,然后递归拷贝初始对象中的各个项目,并且将递归拷贝创建的对象与列表对象关联起来。在深拷贝的场景中,被拷贝的对象被拷贝为其他对象,也就是说在拷贝操作创建的新对象上所做的任何修改,都不会反射到初始的背靠背对象上。而在Python中,这是通过copy.deepcopy()方法实现的。

# Python code to demonstrate copy operations
# importing "copy" for copy operations
import copy

# initializing list 1
li1 = [1, 2, [3, 5], 4]

# using deepcopy to deep copy
li2 = copy.deepcopy(li1)

# original elements of list
print("The original elements before deep copying")
for i in range(0, len(li1)):
	print(li1[i], end=" ")

print("\r")


# new list li2
print("The new list of elements ")
for i in range(0, len(li1)):
	print(li2[i],end=" ")


print("\r")


# adding and element to new list
li2[2][0] = 7

# Change is reflected in l2
print("The new list of elements after modify")
for i in range(0, len(li1)):
	print(li2[i],end=" ")

print("\r")

# Change is NOT reflected in original list
# as it is a deep copy
print("The original elements after modify new list")
for i in range(0, len(li1)):
	print(li1[i],end=" ")

上述代码的输出结果:

The original elements before deep copying
1 2 [3, 5] 4 
The new list of elements 
1 2 [3, 5] 4 
The new list of elements after modify
1 2 [7, 5] 4 
The original elements after modify new list
1 2 [3, 5] 4 
Process finished with exit code 0

在上面的示例中,在拷贝操作创建的新列表上的操作,并没有改变初始列表对象中的项目。说明,li2是深拷贝创建的列表对象。

1.2. Shallow copy——浅拷贝

在这里插入图片描述浅拷贝操作会创建新的变量,然后将这个变量与初始被拷贝的对象关联起来,在此过程中,并没有递归一个与初始被拷贝对象相同的对象出来,只是将变量与初始被拷贝的对象关联起来而已。在浅拷贝的场景中,这种对象引用关系被复制到新的变量上。也就意味着对浅拷贝创建的变量所指代对象的任何修改,最终都会反映到初始被拷贝的对象上面。在Python中,浅拷贝操作是通过copy.copy()方法函数实现的。

# Python code to demonstrate copy operations
# importing "copy" for copy operations
import copy

# initializing list 1
li1 = [1, 2, [3, 5], 4]

# using copy to shallow copy
li2 = copy.copy(li1)

# original elements of list
print("The original elements before modify new list")
for i in range(0, len(li1)):
    print(li1[i], end=" ")

print("\r")

# shallow copy elements of new list
print("The new elements before modify new list")
for i in range(0, len(li1)):
    print(li1[i], end=" ")

print("\r")

# adding and element to new list
li2[2][0] = 7

# new elements of new list after modify new list
print("The new elements before modify new list")
for i in range(0, len(li1)):
    print(li2[i], end=" ")

print("\r")

# checking if change is reflected
print("The original elements after modify new list")
for i in range(0, len(li1)):
    print(li1[i], end=" ")

上述代码的执行结果如下所示:

The original elements before modify new list
1 2 [3, 5] 4 
The new elements before modify new list
1 2 [3, 5] 4 
The new elements before modify new list
1 2 [7, 5] 4 
The original elements after modify new list
1 2 [7, 5] 4 
Process finished with exit code 0

在上述的示例中,对于浅拷贝构建出来的新列表对象li2,在其上所做的修改都会直接反映在初始列表对象上。这也恰恰证明了浅拷贝的特性。

1.3. 关于浅拷贝和深拷贝的关键点

浅拷贝和深拷贝之间的区别,主要反映在它们引用的对象上,即变量所指向的对象是相同的对象,还是递归创建出来的新的对象。另外,要体现出深拷贝与浅拷贝之间的差异,这个对象的组成项目需要包含其他对象,比如嵌套的列表,或者类实例对象:

  • 浅拷贝构建一个新的变量,并且复制初始变量与其引用的对象之间的引用关系,是的新的变量与初始变量指向相同的对象。所以这个过程中,并没有创建新的对象出来。
  • 深拷贝构建一个新的变量,并且以初始变量指向的对象作为蓝本,递归创建一组相同的对象。所以此时新的变量和初始变量引用的是不同的对象。在深拷贝的过程中,递归创建了新的对象出来。

2. 说明列表和元组的相同点和差异

2.1. list和tuple的相同点

  1. 任意类型对象的有序集合
  2. 支持位置偏移索引访问其中的项目
  3. 支持任意层级的嵌套
  4. 存储的是对象的引用关系

2.2. list和tuple的差异

  1. list是可变类型,支持就地修改;tuple是不可变类型,不支持就地修改。
  2. list是变长的,在创建好之后,可以增加、减少其中的项目;tuple是固定长度的,在创建之后,无法对其进行修改。

3. 字符串支持的所有方法以及说明

字符串支持的方法函数如下所示:

  1. str.capitalize:将字符串的首字母大写。

    具体效果如下所示:

    In [227]: str1 = 'hello world'
    In [228]: str1.capitalize()
    Out[228]: 'Hello world'
    

    该方法只是返回字符串中的首字母大写之后的结果,并不会将所有单词的首字母都大写。

  2. str.casefold:返回的结果没有大小写的差异,即将字符串中的所有大写字母转换为小写字母。

    具体效果如下所示:

    In [232]: str2 = 'Hello World'
    In [233]: str2.casefold()
    Out[233]: 'hello world'
    In [234]: str3 = 'HeLLo WoRlD'
    In [235]: str3.casefold()
    Out[235]: 'hello world'
    

    该方法返回的结果为字符串的小写形式。

  3. str.center:指定字符串的输出宽度(需要比字符串的长度大一些,才能看出效果),然后根据该宽度,返回居中显示的字符串。

    具体效果如下所示:

    In [246]: str2
    Out[246]: 'Hello World'
    In [247]: str2.center(20)
    Out[247]: '    Hello World     '
    In [248]: str2.center(20, fillchar='*')
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-248-dba74ecf95af> in <module>
    ----> 1 str2.center(20, fillchar='*')
    TypeError: center() takes no keyword arguments
    
    In [249]: str2.center(20, '*')
    Out[249]: '****Hello World*****'
    

    上述方法并不支持键值对形式传递参数。虽然在该方法的帮助信息中,列出了键值对方式传递参数。具体如下所示:

    center(width, fillchar=' ', /) method of builtins.str instance
    Return a centered string of length width.

  4. str.count:统计指定开始和结束位置的字符串中,指定的子字符串出现的次数。如果不指定起始和结束位置,则从完整的字符串中搜索子字符串的出现次数。

    该方法函数的帮助信息如下所示:

    count(...) method of builtins.str instance
    S.count(sub[, start[, end]]) -> int

    Return the number of non-overlapping occurrences of substring sub in string S[start:end]. Optional arguments start and end are interpreted as in slice notation.

    该方法的执行效果如下所示:

    In [253]: str4 = 'hello world, how are you? fine, thank you, and you?'
    In [254]: str4.count('you')
    Out[254]: 3
    In [255]: str4.index('you')
    Out[255]: 21
    In [256]: str4.count('you', 23, -1)
    Out[256]: 2
    

    在上述的结果中,可以看出,默认情况下是从这个字符串中搜索指定字符串的出现次数。当指定了起止范围之后,则是在指定的范围内统计指定的字符串出现的次数。

  5. str.encode:使用指定的编码方法对字符串进行编码。

    该方法的帮助信息如下所示:

    encode(encoding='utf-8', errors='strict') method of builtins.str instance
    Encode the string using the codec registered for encoding.

    encoding
    The encoding in which to encode the string.
    errors
    The error handling scheme to use for encoding errors.
    The default is ‘strict’ meaning that encoding errors raise a
    UnicodeEncodeError. Other possible values are ‘ignore’, ‘replace’ and
    ‘xmlcharrefreplace’ as well as any other name registered with
    codecs.register_error that can handle UnicodeEncodeErrors.

    该方法的执行效果如下所示:

    In [265]: str3.encode(encoding='ascii')
    Out[265]: b'HeLLo WoRlD'
    In [266]: str3.encode(encoding='utf-8')
    Out[266]: b'HeLLo WoRlD'
    In [267]: type(str3.encode('ascii'))
    Out[267]: bytes
    
    In [269]: str3
    Out[269]: 'HeLLo WoRlD'
    In [270]: str3.encode('base64','strict')
    ---------------------------------------------------------------------------
    LookupError                               Traceback (most recent call last)
    <ipython-input-270-21e80b76cef0> in <module>
    ----> 1 str3.encode('base64','strict')
    
    LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbi
    trary codecs
    

    在Windows 10系统上不支持使用base64对字符串进行编码。更多编码方法,参见官方文档:Standard Encodings

  6. str.endswith:在指定的范围内检查字符串是否以指定的字符或者字符串结尾,如果是,返回True,否则返回False。

    该方法的帮助信息如下所示:

    endswith(...) method of builtins.str instance
    S.endswith(suffix[, start[, end]]) -> bool

    Return True if S ends with the specified suffix, False otherwise.
    With optional start, test S beginning at that position.
    With optional end, stop comparing S at that position.
    suffix can also be a tuple of strings to try.

    该方法的执行效果如下所示:

    In [272]: str3.endswith('D')
    Out[272]: True
    
    In [273]: str3
    Out[273]: 'HeLLo WoRlD'
    

    上述执行结果返回True,即变量str3指向的字符串确实是以’D’结尾的。

  7. str.expandtabs:该方法用于将字符串中包含的tab符转换为空格符。

    该方法的帮助信息如下所示:

    expandtabs(tabsize=8) method of builtins.str instance
    Return a copy where all tab characters are expanded using spaces.

    If tabsize is not given, a tab size of 8 characters is assumed.

    该方法的执行效果如下所示:

    In [276]: str5 = 'Hello\tWorld'
    
    In [277]: print(str5)
    Hello   World
    
    In [278]: str5.expandtabs(tabsize=12)
    Out[278]: 'Hello       World'
    
  8. str.find:该方法用于在指定范围的字符串中,搜索指定的字符串或者字符。如果找到,返回字符串起始位置的索引值;如果找不到,则返回-1。

    该方法的帮助信息如下所示:

    find(…) method of builtins.str instance
    S.find(sub[, start[, end]]) -> int

    Return the lowest index in S where substring sub is found,
    such that sub is contained within S[start:end]. Optional
    arguments start and end are interpreted as in slice notation.

    Return -1 on failure.

    该方法的执行效果如下所示:

    In [281]: str3
    Out[281]: 'HeLLo WoRlD'
    
    In [282]: str3.find('R')
    Out[282]: 8
    
    In [283]: str3[8]
    Out[283]: 'R'
    
  9. str.format:该方法用于格式化打印字符串。

    该方法的帮助信息具体如下所示:

    format(…) method of builtins.str instance
    S.format(*args, **kwargs) -> str

    Return a formatted version of S, using substitutions from args and kwargs.
    The substitutions are identified by braces (‘{’ and ‘}’).

    该方法的执行效果如下所示:

    In [286]: 'hello, this is {0:s}, I love {1:s}'.format('world', 'Python')
    Out[286]: 'hello, this is world, I love Python'
    

    关于该方法的更详细解释,参见库手册:Formatted String Literals

  10. str.format_map:该方法使用字典作为参数,指定要替换的字符串信息。

    该方法的帮助信息如下所示:

    format_map(…) method of builtins.str instance
    S.format_map(mapping) -> str

    Return a formatted version of S, using substitutions from mapping.
    The substitutions are identified by braces (‘{’ and ‘}’).

    该方法的执行效果如下所示:

    In [288]: profession = { 'name':['Barry', 'Bruce'],
         ...:                'profession':['Engineer', 'Doctor'],
         ...:                'age':[30, 31] }
    
    In [289]: print('{name[0]} is an {profession[0]} and he'
         ...:       ' is {age[0]} years old.'.format_map(profession))
    Barry is an Engineer and he is 30 years old.
    
    In [290]: print('{name[1]} is an {profession[1]} and he'
         ...:       ' is {age[1]} years old.'.format_map(profession))
    Bruce is an Doctor and he is 31 years old.
    

    关于该方法的更多示例信息,参见String format_map

  11. str.index:该方法返回指定范围的字符串中,指定的字符或者指定字符串的起始位置。

    该方法的帮助信息如下所示:

    index(…) method of builtins.str instance
    S.index(sub[, start[, end]]) -> int

    Return the lowest index in S where substring sub is found,
    such that sub is contained within S[start:end]. Optional
    arguments start and end are interpreted as in slice notation.

    Raises ValueError when the substring is not found.

    该方法的执行效果如下所示:

    In [295]: str3
    Out[295]: 'HeLLo WoRlD'
    
    In [296]: str3.index('L')
    Out[296]: 2
    
    In [297]: str3[2]
    Out[297]: 'L'
    
  12. str.isalnum:该方法用于判断字符串是否由字母和数字组成。如果是,则返回True,否则返回False。

    该方法的执行效果如下所示:

    In [301]: str6 = 'h3ll0w0r1d'
    
    In [302]: str6.isalnum()
    Out[302]: True
    
    In [303]: str3
    Out[303]: 'HeLLo WoRlD'
    
    In [304]: str3.isalnum()
    Out[304]: False
    
  13. str.isalpha:用于判断指定的字符串是否由字母组成的。如果是,则返回True,否则返回False。

    该方法的执行效果如下所示:

    In [310]: str7 = 'HelloWorld'
    
    In [311]: str7.isalpha()
    Out[311]: True
    
    In [312]: str6 = 'h3ll0w0r1d'
    
    In [313]: str6.isalpha()
    Out[313]: False
    
    In [314]: str3
    Out[314]: 'HeLLo WoRlD'
    
    In [315]: str3.isalpha()
    Out[315]: False
    
  14. str.isascii:该方法用于判断指定的字符串是否为ASCII编码。如果是则返回True,否则返回False。

    该方法的效果如下所示:

    In [318]: str3
    Out[318]: 'HeLLo WoRlD'
    
    In [319]: str3.isascii()
    Out[319]: True
    
    In [320]: str6
    Out[320]: 'h3ll0w0r1d'
    
    In [321]: str6.isascii()
    Out[321]: True
    
    In [322]: str8 = 'Hello蟒蛇'
    
    In [323]: str8.isascii()
    Out[323]: False
    
  15. str.isdecimal:该方法用于判断给定的字符串是否为数字组成的字符串。如果是则返回True,否则返回False。

    该方法的执行效果如下所示:

    In [325]: str6
    Out[325]: 'h3ll0w0r1d'
    
    In [326]: str6.isdecimal()
    Out[326]: False
    
    In [327]: str9 = '12345'
    
    In [328]: str9.isdecimal()
    Out[328]: True
    
  16. str.isdigit:该方法用于判断给定的字符串是否为数字字符串。

    该方法的执行效果具体如下所示:

    In [330]: str9
    Out[330]: '12345'
    
    In [331]: str9.isdigit()
    Out[331]: True
    
    In [332]: str10 = '12345.6789'
    
    In [333]: str10.isdigit()
    Out[333]: False
    

    数字字符串中,只能包含数字,不能包含其他字符。

  17. str.isidentifier:该方法用于判断给定的字符串是否是有效的标识符。

    该方法的执行效果如下所示:

    In [339]: str6
    Out[339]: 'h3ll0w0r1d'
    
    In [340]: str6.isidentifier()
    Out[340]: True
    
    In [341]: str8
    Out[341]: 'Hello蟒蛇'
    
    In [342]: str8.isidentifier()
    Out[342]: True
    
    In [343]: str7
    Out[343]: 'HelloWorld'
    
    In [344]: str9
    Out[344]: '12345'
    
    In [345]: str9.isidentifier()
    Out[345]: False
    

    有点儿像检查变量名是否符合变量名命名规范,但又不同,变量名命名规范要求变量名由字母、数字和下划线组成,且不能以数字开头。

    与该方法类似,keyword模块还有一个keyword.iskeyword方法,用于判断给定的字符串是否为Python的预留关键字。如下所示:

    In [346]: import keyword
    
    In [347]: keyword.iskeyword('def')
    Out[347]: True
    
  18. str.islower:用于判断给定的字符串是否为小写。

    该方法的执行效果如下所示:

    In [352]: str3
    Out[352]: 'HeLLo WoRlD'
    
    In [353]: str3.islower()
    Out[353]: False
    
    In [354]: str6
    Out[354]: 'h3ll0w0r1d'
    
    In [355]: str6.islower()
    Out[355]: True
    
    In [356]: str10
    Out[356]: '12345.6789'
    
    In [357]: str10.islower()
    Out[357]: False
    

    字符串中如果含有数字,同时字符串是小写字母组成,那么也是可以进行判断的。

  19. str.isnumeric:用于判断给定的字符串是否为数字字符串。

    该方法的执行效果如下所示:

    In [359]: str10
    Out[359]: '12345.6789'
    
    In [360]: str10.isnumeric()
    Out[360]: False
    
    In [361]: str9
    Out[361]: '12345'
    
    In [362]: str9.isnumeric()
    Out[362]: True
    

    对于数字字符串中,要求不能有空格。

  20. str.isprintable:用于判断字符串是否为可打印的字符。

    该方法的使用效果如下所示:

    In [367]: str5
    Out[367]: 'Hello\tWorld'
    
    In [368]: str5.isprintable()
    Out[368]: False
    
    In [369]: str4
    Out[369]: 'hello world, how are you? fine, thank you, and you?'
    
    In [370]: str4.isprintable()
    Out[370]: True
    
    In [371]: str3.isprintable()
    Out[371]: True
    
    In [372]: str11 = 'Hello\nWorld'
    
    In [373]: str11.isprintable()
    Out[373]: False
    

    从上述结果中可以看出,空格以及其他标点符号,是属于可打印字符;而制表符(\t)以及回车符(\n)则不属于可打印字符。

  21. str.isspace:用于判断指定的字符串是否为空白字符串。

    该方法的效果如下所示:

    In [376]: str12 = ''
    
    In [377]: str12.isspace()
    Out[377]: False
    
    In [378]: str13 = ' '
    
    In [379]: str13.isspace()
    Out[379]: True
    
    In [380]: str3
    Out[380]: 'HeLLo WoRlD'
    
    In [381]: str3.isspace()
    Out[381]: False
    
    In [382]: str14 = '\t'
    
    In [383]: str14.isspace()
    Out[383]: True
    
    In [384]: str15 = '\n'
    
    In [385]: str15.isspace()
    Out[385]: True
    

    从上述代码中可以看出,空白符、回车符、制表符都属于空白符。

  22. str.istitle:用于判断给定的字符串是否符合标题样式,即只有每个单词的首字母都大写的时候才符合。如果符合则返回True,否则返回False。

    该方法的使用效果如下所示:

    In [387]: str4
    Out[387]: 'hello world, how are you? fine, thank you, and you?'
    
    In [388]: str4.istitle()
    Out[388]: False
    
    In [389]: str3
    Out[389]: 'HeLLo WoRlD'
    
    In [390]: str3.istitle()
    Out[390]: False
    
    In [391]: 'HELLO WORLD'.istitle()
    Out[391]: False
    
    In [392]: 'Hello World'.istitle()
    Out[392]: True
    

    从上述输出中可以看出,只有当每个单词的首字母都是大写的时候,且大写字母之后必须为小写字母的时候,才符合条件。

  23. str.isupper:用于判断给定的字符串是否为大写字符串。如果是,则返回True,否则返回False。

    该方法的效果如下所示:

    In [394]: 'HELLO WORLD'.isupper()
    Out[394]: True
    
    In [395]: 'Hello WORLD'.isupper()
    Out[395]: False
    
  24. str.join:该方法用于将任意数量的字符串使用指定的分隔符连接在一起。多个需要连接的字符串需要放在可迭代类型对象中。

    该方法的帮助信息如下所示:

    join(iterable, /) method of builtins.str instance
    Concatenate any number of strings.

    The string whose method is called is inserted in between each given string.
    The result is returned as a new string.

    Example: '.'.join(['ab', 'pq', 'rs']) -> ‘ab.pq.rs’

    该方法的使用效果如下所示:

    In [397]: '=*='.join(('hello', 'world', 'I', 'love', 'Python'))
    Out[397]: 'hello=*=world=*=I=*=love=*=Python'
    
  25. str.ljust:该方法用于指定字符串的显示宽度,并且采用左对齐的方式显示,当字符串的长度小于指定的宽度时候,采用fillchar填充字符串的右侧。

    该方法的帮助信息如下所示:

    ljust(width, fillchar=' ', /) method of builtins.str instance
    Return a left-justified string of length width.

    Padding is done using the specified fill character (default is a space).

    该方法的使用效果如下所示:

    In [399]: 'Hello World'.ljust(20, '+')
    Out[399]: 'Hello World+++++++++'
    
  26. str.lower:该方法用于将指定的字符串转换为小写。

    该方法的执行效果如下所示:

    In [401]: 'HELLO WOrld, 132'.lower()
    Out[401]: 'hello world, 132'
    
  27. str.lstrip:这个命令用于剔除字符串左侧的空白符(空格,回车符,制表符等)。

    该命令的效果如下所示:

    In [403]: ' Hello World '.lstrip()
    Out[403]: 'Hello World '
    
    In [404]: '\tHello World '.lstrip()
    Out[404]: 'Hello World '
    
    In [405]: '\nHello World '.lstrip()
    Out[405]: 'Hello World '
    

    注意,空白符需要是字符串的第一个字符。

  28. str.maketrans:返回一个str.translate()函数可以使用的翻译表。

    该方法的帮助信息如下所示:

    maketrans(x, y=None, z=None, /)
    Return a translation table usable for str.translate().

    If there is only one argument, it must be a dictionary mapping Unicode
    ordinals (integers) or characters to Unicode ordinals, strings or None.
    Character keys will be then converted to ordinals.

    If there are two arguments, they must be strings of equal length, and
    in the resulting dictionary, each character in x will be mapped to the
    character at the same position in y. If there is a third argument, it
    must be a string, whose characters will be mapped to None in the result.

    该方法的效果如下所示:

    • 带一个参数的时候,要求该参数是一个字典。示例如下:

      In [407]: dict= {"a": "123", "b": "456", "c": "789"}
      In [408]: my_string = "abc"
      In [409]: print(my_string.maketrans(dict))
      {97: '123', 98: '456', 99: '789'}
      
      In [411]: dict = {97: "123", 98: "456", 99: "789"}
      In [412]: my_string = "abc"
      In [413]: print(my_string.maketrans(dict))
      {97: '123', 98: '456', 99: '789'}
      
    • 带两个参数的时候,要求这两个参数是等长的字符串。具体如下所示:

      In [414]: my_string1 = "abc"
      In [415]: my_string2 = "def"
      In [416]: string = "abc"
      In [417]: print(string.maketrans(my_string1, my_string2))
      {97: 100, 98: 101, 99: 102}
      
      In [419]: my_string1 = "abc"
      In [420]: my_string2 = "defghi"
      In [421]: string = "abc"
      In [422]: print(string.maketrans(my_string1, my_string2))
      ---------------------------------------------------------------------------
      ValueError                                Traceback (most recent call last)
      <ipython-input-422-945a562d4595> in <module>
      ----> 1 print(string.maketrans(my_string1, my_string2))
      ValueError: the first two maketrans arguments must have equal length
      

    更多关于该方法函数的示例,参见str.maketrans

  29. str.partition:该方法用于将字符串使用指定的分隔符分为三部分。如果指定的分隔符在字符串中被搜索到,那么返回一个包含三个项目的元组:分隔符前面的字符串,分隔符自身,以及分隔符后面的部分。如果字符串中不包含指定的分隔符,那么也会返回一个包含三个项目的元组:字符串本身,以及2个空字符串。

    该命令的使用效果如下所示:

    In [424]: str4
    Out[424]: 'hello world, how are you? fine, thank you, and you?'
    
    In [425]: str4.partition(',')
    Out[425]: ('hello world', ',', ' how are you? fine, thank you, and you?')
    
    In [426]: str3
    Out[426]: 'HeLLo WoRlD'
    
    In [427]: str3.partition(' ')
    Out[427]: ('HeLLo', ' ', 'WoRlD')
    
  30. str.replace:用于使用新的子字符串替换字符串中搜索到的旧的字符串,并返回替换后的结果。

    该方法的帮助信息如下所示:

    replace(old, new, count=-1, /) method of builtins.str instance
    Return a copy with all occurrences of substring old replaced by new.

    count
    Maximum number of occurrences to replace.
    -1 (the default value) means replace all occurrences.

    If the optional argument count is given, only the first count occurrences are replaced.

    该方法的使用效果如下所示:

    In [429]: str4
    Out[429]: 'hello world, how are you? fine, thank you, and you?'
    
    In [430]: str4.replace('you', 'Jungle')
    Out[430]: 'hello world, how are Jungle? fine, thank Jungle, and Jungle?'
    
    In [431]: str4.replace('you', 'Jungle', 2)
    Out[431]: 'hello world, how are Jungle? fine, thank Jungle, and you?'
    

    如果只指定旧字符串,以及替换后的新字符串,不指定替换操作执行的次数,那么默认会替换所有搜索到的旧字符串。如果指定了替换操作执行的次数,那么只替换操作只执行指定的次数。

  31. str.rfind:该方法用于从指定的范围的字符串中,查找特定的字符串。并返回找到的字符串的第一个字符的索引位置。如果有多个匹配结果,则返回最后一个匹配结果的第一个字符的索引位置。如果找不到,则返回-1。

    该方法的帮助信息如下所示:

    rfind(…) method of builtins.str instance
    S.rfind(sub[, start[, end]]) -> int

    Return the highest index in S where substring sub is found,
    such that sub is contained within S[start:end]. Optional
    arguments start and end are interpreted as in slice notation.

    Return -1 on failure.

    该方法的执行效果如下所示:

    In [433]: str4
    Out[433]: 'hello world, how are you? fine, thank you, and you?'
    
    In [434]: str4.rfind('thank')
    Out[434]: 32
    
    In [435]: str4[32]
    Out[435]: 't'
    
    In [436]: str4.rfind('you')
    Out[436]: 47
    
    In [437]: str4[47]
    Out[437]: 'y'
    
    In [438]: len(str4)
    Out[438]: 51
    
  32. str.rindex:从指定范围的字符串中搜索特定的字符串。如果找到,则返回该字符串的第一个字符的索引位置。如果有多个匹配结果,则返回最后一个匹配结果的第一个字符的索引位置。如果没有匹配结果,则返回-1。

    该方法的帮助信息如下所示:

    rindex(…) method of builtins.str instance
    S.rindex(sub[, start[, end]]) -> int

    Return the highest index in S where substring sub is found,
    such that sub is contained within S[start:end]. Optional
    arguments start and end are interpreted as in slice notation.

    Raises ValueError when the substring is not found.

    该方法的使用效果如下所示:

    In [440]: str4
    Out[440]: 'hello world, how are you? fine, thank you, and you?'
    
    In [441]: str4.rindex('you')
    Out[441]: 47
    
    In [442]: len(str4)
    Out[442]: 51
    
    In [443]: str4[47]
    Out[443]: 'y'
    
  33. str.rjust:该方法用于使用指定的宽度显示字符串,同时当宽度大于字符串的长度时,使字符串居右对齐,左侧补齐填充字符。

    该方法的帮助信息如下所示:

    rjust(width, fillchar=' ', /) method of builtins.str instance
    Return a right-justified string of length width.

    Padding is done using the specified fill character (default is a space).

    该方法的执行效果如下所示:

    In [448]: str2
    Out[448]: 'Hello World'
    
    In [449]: str2.rjust(20, '&')
    Out[449]: '&&&&&&&&&Hello World'
    
  34. str.rpartition:该方法从字符串的末尾开始向前搜索指定的分隔符,并且返回一个由三个项目组成的元组。如果该分隔符被搜索到,则返回分隔符前面的字符串、分隔符自身以及分隔符后面的字符串三部分;如果该分隔符未被找到,则返回完整的字符串以及两个空白字符串。

    该方法的执行效果如下所示:

    In [451]: str4
    Out[451]: 'hello world, how are you? fine, thank you, and you?'
    
    In [452]: str4.rpartition(',')
    Out[452]: ('hello world, how are you? fine, thank you', ',', ' and you?')
    
  35. str.rsplit:该方法返回列表,列表中的项目为字符串使用指定的分隔符分隔而成的。

    该方法的帮助信息如下所示:

    rsplit(sep=None, maxsplit=-1) method of builtins.str instance
    Return a list of the words in the string, using sep as the delimiter string.

    sep
    The delimiter according which to split the string.
    None (the default value) means split according to any whitespace,
    and discard empty strings from the result.
    maxsplit
    Maximum number of splits to do.
    -1 (the default value) means no limit.

    Splits are done starting at the end of the string and working to the front.

    该方法的效果如下所示:

    In [454]: str4
    Out[454]: 'hello world, how are you? fine, thank you, and you?'
    
    In [455]: str4.rsplit(',')
    Out[455]: ['hello world', ' how are you? fine', ' thank you', ' and you?']
    

    该方法无论是执行效果还是帮助信息,都没有看出与str.split函数的区别之处。

  36. str.rstrip:该方法移除字符串末尾的空白符(空格、制表符、回车符等)。

    该方法的执行效果如下所示:

    In [464]: 'Hello World '.rstrip()
    Out[464]: 'Hello World'
    
    In [465]: ' Hello World '.rstrip()
    Out[465]: ' Hello World'
    
    In [466]: '\tHello World\t'.rstrip()
    Out[466]: '\tHello World'
    
    In [467]: '\nHello\nWorld\n'.rstrip()
    Out[467]: '\nHello\nWorld'
    
  37. str.split:该方法返回一个列表对象,列表对象的项目为特定字符分隔的字符串。

    该方法的帮助信息如下所示:

    split(sep=None, maxsplit=-1) method of builtins.str instance
    Return a list of the words in the string, using sep as the delimiter string.

    sep
    The delimiter according which to split the string.
    None (the default value) means split according to any whitespace,
    and discard empty strings from the result.
    maxsplit
    Maximum number of splits to do.
    -1 (the default value) means no limit.

    该方法的执行效果如下所示:

    In [469]: str4
    Out[469]: 'hello world, how are you? fine, thank you, and you?'
    
    In [470]: str4.split(',')
    Out[470]: ['hello world', ' how are you? fine', ' thank you', ' and you?']
    
  38. str.splitlines:该方法返回一个列表,列表中的项目为换行符作为分隔符隔开的子字符串。

    该方法的执行效果如下所示:

    In [472]: str4
    Out[472]: 'hello world, how are you? fine, thank you, and you?'
    
    In [473]: str4.splitlines()
    Out[473]: ['hello world, how are you? fine, thank you, and you?']
    
    In [474]: 'Hello\nWorld'.splitlines()
    Out[474]: ['Hello', 'World']
    
    In [475]: 'Hello\nWorld'.splitlines(True)
    Out[475]: ['Hello\n', 'World']
    
    In [477]: 'Hello\nWorld'.splitlines(keepends=True)
    Out[477]: ['Hello\n', 'World']
    

    该方法默认不带换行符,如果指定选项keepends=True,则也将换行符加入到分隔后的字符串中。

  39. str.startswith:该方法用于判断指定范围的字符串是否以特定的字符串开头。如果是,则返回True,否则返回False。

    该方法的帮助信息如下所示:

    startswith(…) method of builtins.str instance
    S.startswith(prefix[, start[, end]]) -> bool

    Return True if S starts with the specified prefix, False otherwise.
    With optional start, test S beginning at that position.
    With optional end, stop comparing S at that position.
    prefix can also be a tuple of strings to try.

    该方法的执行效果如下所示:

    In [480]: str3
    Out[480]: 'HeLLo WoRlD'
    
    In [481]: str3.startswith('H')
    Out[481]: True
    
    In [482]: str3.startswith('W')
    Out[482]: False
    
  40. str.strip:该方法用于将字符串开头和末尾的空白符删除。

    该方法的执行效果如下所示:

    In [484]: ' Hello World '.strip()
    Out[484]: 'Hello World'
    
    In [485]: '\tHello\tWorld\t'.strip()
    Out[485]: 'Hello\tWorld'
    
    In [486]: '\nHello\nWorld\n'.strip()
    Out[486]: 'Hello\nWorld'
    
  41. str.swapcase:该方法用于将字符串中的大小写字符转换,即原来的大写字符转换为小写字符;原来的小写字符转换为大写字符。

    该方法的执行效果如下所示:

    In [489]: str3
    Out[489]: 'HeLLo WoRlD'
    
    In [490]: str3.swapcase()
    Out[490]: 'hEllO wOrLd'
    
  42. str.title:该方法用于将字符串中的每个单词首字母都改为大写,其他字符保持为小写的形式。

    该方法的执行效果如下所示:

    In [492]: str4
    Out[492]: 'hello world, how are you? fine, thank you, and you?'
    
    In [493]: str4.title()
    Out[493]: 'Hello World, How Are You? Fine, Thank You, And You?'
    
  43. str.translate:这个方法用于使用指定的翻译表替换字符串中的字符。翻译表可以使用str.maketrans方法函数生成。所以这个函数通常依赖于str.maketrans方法函数。

    该方法的执行效果如下所示:

    In [499]: inp_str = 'Hello from AskPython'
    In [500]: translation = str.maketrans('As', 'ab', 'e')
    In [501]: out_str = inp_str.translate(translation)
    In [502]: print(out_str)
    Hllo from abkPython
    

    其中str.maketrans生成的翻译表为一个字典。其内容以及类型如下所示:

    In [503]: type(translation)
    Out[503]: dict
    
    In [504]: print(translation)
    {65: 97, 115: 98, 101: None}
    

    更多关于这个方法函数的使用示例参见String Translate

  44. str.upper:该方法用于将字符串转换为大写。

    该方法的使用效果如下所示:

    In [506]: str2
    Out[506]: 'Hello World'
    
    In [507]: str2.upper()
    Out[507]: 'HELLO WORLD'
    
  45. str.zfill:该方法用于使用指定的宽度显示字符串,当宽度大于字符串长度的时候,将字符串的左侧使用0填充。

    该方法的帮助信息如下所示:

    zfill(width, /) method of builtins.str instance
    Pad a numeric string with zeros on the left, to fill a field of the given width.

    The string is never truncated.

    该方法的使用效果如下所示:

    In [510]: str2
    Out[510]: 'Hello World'
    
    In [511]: str2.zfill(20)
    Out[511]: '000000000Hello World'
    

至此,字符串支持的45个方法以及简单示例就整理完成了。

4. 使用选择排序算法实现列表元素的排序

排序对象[3, 5, 1, 7, 9, 6, 8]

选择排序,是众多排序算法中的一种,它总是在每次迭代中,从未排序的列表中选择最小的一个项目,并将这个项目放在未排序列表的起始位置。更多排序算法,参照 a sorting algorithm


4.1. 选择排序算法的执行过程

  1. 将列表中的第一个项目设置为最小的,即假设它为minimum。具体如下图所示:
    在这里插入图片描述2. 将这个最小值与第二个项目相比。如果第二个项目比minimum小,那么将第二个项目设置为minimum
    接下来比较第三个项目,如果第三个项目也比minimum小,那么将minimum设置为第三个项目,否则就不做处理。持续这个过程,知道将列表迭代完成。这个过程具体如下图所示:
    在这里插入图片描述3. 在每次迭代之后,都将最小的值放在未排序列表的前面。
    在这里插入图片描述
    4.对于每次迭代,索引都是从未排序列表的第一个项目开始的。会一直重复下面的step1到step3的过程,直到列表中所有的项目都处在正确的位置位置。
    在这里插入图片描述上图为第一次迭代。
    在这里插入图片描述上图为第二次迭代。
    在这里插入图片描述上图为第3此迭代。
    在这里插入图片描述1. 上图为第四次迭代。

4.2. 选择排序算法伪代码

selectionSort(array, size)
  repeat (size - 1) times		# 外层循环
  set the first unsorted element as the minimum
  for each of the unsorted elements		# 内层嵌套循环
    if element < currentMinimum
      set element as new minimum
  swap minimum with first unsorted position
end selectionSort

上述伪代码中给出了选择排序的逻辑过程,采用两层嵌套循环的方式实现这个算法。外层循环每迭代一次,将当次循环的循环变量作为列表的索引,并将该索引指向的值标识为假定的最小值。并在内层循环中使用这个假定的最小值判断列表中这个最小值后面的各个元素,是否比这个最小值小,如果小于这个最小值,那么将这个元素设置为最小值,同时将外层循环的循环变量指向的值与这个最小值之间互换位置,如此迭代直至内层循环完成。内层循环遍历完成之后,此时就求出了第一个最小的值。

接下来开启下一轮外层循环,此时同样将外层循环变量作为索引,此索引在列表中对应的值作为假定的下一轮内存循环的最小值,求取列表中第二个最小值。外层循环每迭代一次,都会求取出当次循环对应的最小值,比如第一次外层循环,求取出列表中最小的值;第二次外层循环,求取出列表中第二小的值,依此类推。

具体算法实现如下。

4.3. 选择排序算法代码实现

这个算法的伪代码以及逻辑过程分析完了,接下来是代码实现。具体如下所示:

# 选择排序算法对列表中的项目进行排序
# 列表内容:[3, 5, 1, 7, 9, 6, 8]


def selection_sort(arr):
    lth = len(arr)
    for out_n in range(lth):
        minimum = arr[out_n]
        for in_n in range(out_n+1, lth):
            if arr[in_n] < minimum:
                cur_minimum = arr[in_n]
                arr[in_n] = minimum
                arr[out_n] = cur_minimum
                minimum = arr[out_n]
    return arr

lst1 = [3, 5, 1, 7, 9, 6, 8, 1]
sorted_lst = selection_sort(lst1)
print(sorted_lst)

上述代码的执行结果如下所示:

[1, 1, 3, 5, 6, 7, 8, 9]

Process finished with exit code 0

在内层循环中的一种更简洁的实现方式如下:

# Selection sort in Python


def selectionSort(array, size):
   
    for step in range(size):
        min_idx = step

        for i in range(step + 1, size):
         
            # to sort in descending order, change > to < in this line
            # select the minimum element in each loop
            if array[i] < array[min_idx]:
                min_idx = i
         
        # put min at the correct position
        (array[step], array[min_idx]) = (array[min_idx], array[step])


data = [-2, 45, 0, 11, -9]
size = len(data)
selectionSort(data, size)
print('Sorted Array in Ascending Order:')
print(data)

上述代码的执行结果如下所示:

Sorted Array in Ascending Order:
[-9, -2, 0, 11, 45]

上述就是选择排序算法的实现过程。

5. 统计日志中每种请求类型的数量

提示: 空格分割的第2列是请求类型,

期望结果:

POST 2

GET 3

日志内容:

下边是logs变量:

logs = ‘’’

111.30.144.7 “POST /mock/login/?t=GET HTTP/1.1” 200

111.30.144.7 “Get /mock/users/?t=POST HTTP/1.1” 200

111.13.100.92 “Post /mock/login/ HTTP/1.1” 200

223.88.60.88 “GET /mock/users/?t=POST HTTP/1.1” 200

111.30.144.7 “GET /mock/users/ HTTP/1.1” 200

‘’’

逻辑分析:

上述日志中,要求取的是空格分隔的第二列,由于后面=号后面有一些干扰因素,所以不能直接使用字符串的count函数,另外第二列中相同的动作,有大写也有小写,所以可以考虑使用字符串的lower方法将字符串转换为小写之后,再调用count函数进行统计。

代码实现:

代码的实现如下所示:

'''
统计如下日志,求出没中访问类型的次数,输入如下形式结果:
POST 2
GET 3
'''


logs = '''
111.30.144.7 "POST /mock/login/?t=GET HTTP/1.1" 200 
111.30.144.7 "Get /mock/users/?t=POST HTTP/1.1" 200 
111.13.100.92 "Post /mock/login/ HTTP/1.1" 200 
223.88.60.88 "GET /mock/users/?t=POST HTTP/1.1" 200 
111.30.144.7 "GET /mock/users/ HTTP/1.1" 200 
'''


def log_analyze(log_cont):
    ln_lst = [x for x in log_cont.split('\n') if x is not '']
    action = ''
    for ln in ln_lst:
        action += ln.split(' ')[1]

    post_num = action.lower().count('post')
    get_num = action.lower().count('get')

    print('POST %d' % post_num)
    print('GET %d' % get_num)

log_analyze(logs)

上述代码的执行结果如下所示:

POST 2
GET 3

Process finished with exit code 0

至此,就实现了期望的结果。

6. References

[1]. Shallow Copy V.S. Deep Copy

[2]. [Selection Sort Algorithm](

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值