像计算机科学家一样学习python(6)

字符串+文字游戏

Python学习笔记-像计算机科学家一样学习python(6)

字符串

Python
prefixes = 'JKLMNOPQ'
suffix = 'ack'

for letter in prefixes:
    if letter == 'O' or letter == 'Q':
        print(letter + 'u' + suffix)
    else:
        print(letter + suffix)

普通函数的调用为call,方法的调用则为invocation。

练习

8-1

字符串的方法

字符串实现了所有 一般 序列的操作,还额外提供了以下列出的一些附加方法。

字符串还支持两种字符串格式化样式,一种提供了很大程度的灵活性和可定制性 (参阅 str.format(), 格式字符串语法自定义字符串格式化) 而另一种是基于 C printf 样式的格式化,它可处理的类型范围较窄,并且更难以正确使用,但对于它可处理的情况往往会更为快速 (printf 风格的字符串格式化)。

标准库的 文本处理服务 部分涵盖了许多其他模块,提供各种文本相关工具(例如包含于 re 模块中的正则表达式支持)。

  • str.capitalize()

    返回原字符串的副本,其首个字符大写,其余为小写。在 3.8 版更改: 第一个字符现在被放入了 titlecase 而不是 uppercase。 这意味着复合字母类字符将只有首个字母改为大写,而再不是全部字符大写。

  • str.casefold()

    返回原字符串消除大小写的副本。 消除大小写的字符串可用于忽略大小写的匹配。消除大小写类似于转为小写,但是更加彻底一些,因为它会移除字符串中的所有大小写变化形式。 例如,德语小写字母 'ß' 相当于 "ss"。 由于它已经是小写了,lower() 不会对 'ß' 做任何改变;而 casefold() 则会将其转换为 "ss"。消除大小写算法的描述请参见 Unicode 标准的 3.13 节。3.3 新版功能.

  • str.center(width[, fillchar])

    返回长度为 width 的字符串,原字符串在其正中。 使用指定的 fillchar 填充两边的空位(默认使用 ASCII 空格符)。 如果 width 小于等于 len(s) 则返回原字符串的副本。

  • str.count(sub[, start[, end]])

    反回子字符串 sub 在 [start, end] 范围内非重叠出现的次数。 可选参数 start 与 end 会被解读为切片表示法。

  • str.encode(encoding="utf-8", errors="strict")

    返回原字符串编码为字节串对象的版本。 默认编码为 'utf-8'。 可以给出 errors 来设置不同的错误处理方案。 errors 的默认值为 'strict',表示编码错误会引发 UnicodeError。 其他可用的值为 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及任何其他通过 codecs.register_error() 注册的值,请参阅 错误处理方案 小节。 要查看可用的编码列表,请参阅 标准编码 小节。在 3.1 版更改: 加入了对关键字参数的支持。

  • str.endswith(suffix[, start[, end]])

    如果字符串以指定的 suffix 结束返回 True,否则返回 False。 suffix 也可以为由多个供查找的后缀构成的元组。 如果有可选项 start,将从所指定位置开始检查。 如果有可选项 end,将在所指定位置停止比较。

  • str.expandtabs(tabsize=8)

    返回字符串的副本,其中所有的制表符会由一个或多个空格替换,具体取决于当前列位置和给定的制表符宽度。 每 tabsize 个字符设为一个制表位(默认值 8 时设定的制表位在列 0, 8, 16 依次类推)。 要展开字符串,当前列将被设为零并逐一检查字符串中的每个字符。 如果字符为制表符 (\t),则会在结果中插入一个或多个空格符,直到当前列等于下一个制表位。 (制表符本身不会被复制。) 如果字符为换行符 (\n) 或回车符 (\r),它会被复制并将当前列重设为零。 任何其他字符会被不加修改地复制并将当前列加一,不论该字符在被打印时会如何显示。>>> '01\t012\t0123\t01234'.expandtabs() '01 012 0123 01234' >>> '01\t012\t0123\t01234'.expandtabs(4) '01 012 0123 01234'

  • str.find(sub[, start[, end]])

    返回子字符串 sub 在 s[start:end] 切片内被找到的最小索引。 可选参数 start 与 end 会被解读为切片表示法。 如果 sub 未被找到则返回 -1。注解 find() 方法应该只在你需要知道 sub 所在位置时使用。 要检查 sub 是否为子字符串,请使用 in 操作符:>>>>>> 'Py' in 'Python' True

  • str.format(args, kwargs)

    执行字符串格式化操作。 调用此方法的字符串可以包含字符串字面值或者以花括号 {} 括起来的替换域。 每个替换域可以包含一个位置参数的数字索引,或者一个关键字参数的名称。 返回的字符串副本中每个替换域都会被替换为对应参数的字符串值。>>> "The sum of 1 + 2 is {0}".format(1+2) 'The sum of 1 + 2 is 3' 请参阅 格式字符串语法 了解有关可以在格式字符串中指定的各种格式选项的说明。注解 当使用 n 类型 (例如: '{:n}'.format(1234)) 来格式化数字 (int, float, complex, decimal.Decimal 及其子类) 的时候,该函数会临时性地将 LC_CTYPE 区域设置为 LC_NUMERIC 区域以解码 localeconv()decimal_pointthousands_sep 字段,如果它们是非 ASCII 字符或长度超过 1 字节的话,并且LC_NUMERIC 区域会与 LC_CTYPE 区域不一致。 这个临时更改会影响其他线程。在 3.7 版更改: 当使用 n 类型格式化数字时,该函数在某些情况下会临时性地将 LC_CTYPE 区域设置为 LC_NUMERIC 区域。

  • str.format_map(mapping)

    类似于 str.format(mapping),不同之处在于 mapping 会被直接使用而不是复制到一个 dict。 适宜使用此方法的一个例子是当 mapping 为 dict 的子类的情况:>>> class Default(dict): ... def __missing__(self, key): ... return key ... >>> '{name} was born in {country}'.format_map(Default(name='Guido')) 'Guido was born in country' 3.2 新版功能.

  • str.index(sub[, start[, end]])

    类似于 find(),但在找不到子类时会引发 ValueError

  • str.isalnum()

    Return True if all characters in the string are alphanumeric and there is at least one character, Falseotherwise. A character c is alphanumeric if one of the following returns True: c.isalpha(), c.isdecimal(),c.isdigit(), or c.isnumeric().

  • str.isalpha()

    Return True if all characters in the string are alphabetic and there is at least one character, False otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different from the "Alphabetic" property defined in the Unicode Standard.

  • str.isascii()

    Return True if the string is empty or all characters in the string are ASCII, False otherwise. ASCII characters have code points in the range U+0000-U+007F.3.7 新版功能.

  • str.isdecimal()

    Return True if all characters in the string are decimal characters and there is at least one character, Falseotherwise. Decimal characters are those that can be used to form numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in the Unicode General Category "Nd".

  • str.isdigit()

    Return True if all characters in the string are digits and there is at least one character, False otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the property value Numeric_Type=Digit or Numeric_Type=Decimal.

  • str.isidentifier()

    Return True if the string is a valid identifier according to the language definition, section 标识符和关键字.调用 keyword.iskeyword() 来检测字符串 s 是否为保留标识符,例如 defclass。示例:>>>>>> from keyword import iskeyword >>> 'hello'.isidentifier(), iskeyword('hello') True, False >>> 'def'.isidentifier(), iskeyword('def') True, True

  • str.islower()

    Return True if all cased characters 4 in the string are lowercase and there is at least one cased character, False otherwise.

  • str.isnumeric()

    Return True if all characters in the string are numeric characters, and there is at least one character, Falseotherwise. Numeric characters include digit characters, and all characters that have the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric characters are those with the property value Numeric_Type=Digit, Numeric_Type=Decimal or Numeric_Type=Numeric.

  • str.isprintable()

    Return True if all characters in the string are printable or the string is empty, False otherwise. Nonprintable characters are those characters defined in the Unicode character database as "Other" or "Separator", excepting the ASCII space (0x20) which is considered printable. (Note that printable characters in this context are those which should not be escaped when repr() is invoked on a string. It has no bearing on the handling of strings written to sys.stdout or sys.stderr.)

  • str.isspace()

    Return True if there are only whitespace characters in the string and there is at least one character, Falseotherwise.空白 字符是指在 Unicode 字符数据库 (参见 unicodedata) 中主要类别为 Zs ("Separator, space") 或所属双向类为 WS, BS 的字符。

  • str.istitle()

    Return True if the string is a titlecased string and there is at least one character, for example uppercase characters may only follow uncased characters and lowercase characters only cased ones. Return Falseotherwise.

  • str.isupper()

    Return True if all cased characters 4 in the string are uppercase and there is at least one cased character, False otherwise.

  • str.join(iterable)

    返回一个由 iterable 中的字符串拼接而成的字符串。 如果 iterable 中存在任何非字符串值包括 bytes 对象则会引发 TypeError。 调用该方法的字符串将作为元素之间的分隔。

  • str.ljust(width[, fillchar])

    返回长度为 width 的字符串,原字符串在其中靠左对齐。 使用指定的 fillchar 填充空位 (默认使用 ASCII 空格符)。 如果 width 小于等于 len(s) 则返回原字符串的副本。

  • str.lower()

    返回原字符串的副本,其所有区分大小写的字符 4 均转换为小写。所用转换小写算法的描述请参见 Unicode 标准的 3.13 节。

  • str.lstrip([chars])

    返回原字符串的副本,移除其中的前导字符。 chars 参数为指定要移除字符的字符串。 如果省略或为 None,则 chars 参数默认移除空格符。 实际上 chars 参数并非指定单个前缀;而是会移除参数值的所有组合:>>>>>> ' spacious '.lstrip() 'spacious ' >>> 'www.example.com'.lstrip('cmowz.') 'example.com'

  • static str.maketrans(x[, y[, z]])

    此静态方法返回一个可供 str.translate() 使用的转换对照表。如果只有一个参数,则它必须是一个将 Unicode 码位序号(整数)或字符(长度为 1 的字符串)映射到 Unicode 码位序号、(任意长度的)字符串或 None 的字典。 字符键将会被转换为码位序号。如果有两个参数,则它们必须是两个长度相等的字符串,并且在结果字典中,x 中每个字符将被映射到 y 中相同位置的字符。 如果有第三个参数,它必须是一个字符串,其中的字符将在结果中被映射到 None

  • str.partition(sep)

    在 sep 首次出现的位置拆分字符串,返回一个 3 元组,其中包含分隔符之前的部分、分隔符本身,以及分隔符之后的部分。 如果分隔符未找到,则返回的 3 元组中包含字符本身以及两个空字符串。

  • str.replace(old, new[, count])

    返回字符串的副本,其中出现的所有子字符串 old 都将被替换为 new。 如果给出了可选参数 count,则只替换前 count 次出现。

  • str.rfind(sub[, start[, end]])

    返回子字符串 sub 在字符串内被找到的最大(最右)索引,这样 sub 将包含在 s[start:end] 当中。 可选参数 start 与 end 会被解读为切片表示法。 如果未找到则返回 -1

  • str.rindex(sub[, start[, end]])

    类似于 rfind(),但在子字符串 sub 未找到时会引发 ValueError

  • str.rjust(width[, fillchar])

    返回长度为 width 的字符串,原字符串在其中靠右对齐。 使用指定的 fillchar 填充空位 (默认使用 ASCII 空格符)。 如果 width 小于等于 len(s) 则返回原字符串的副本。

  • str.rpartition(sep)

    在 sep 最后一次出现的位置拆分字符串,返回一个 3 元组,其中包含分隔符之前的部分、分隔符本身,以及分隔符之后的部分。 如果分隔符未找到,则返回的 3 元组中包含两个空字符串以及字符串本身。

  • str.rsplit(sep=None, maxsplit=-1)

    返回一个由字符串内单词组成的列表,使用 sep 作为分隔字符串。 如果给出了 maxsplit,则最多进行 maxsplit 次拆分,从 最右边 开始。 如果 sep 未指定或为 None,任何空白字符串都会被作为分隔符。 除了从右边开始拆分,rsplit() 的其他行为都类似于下文所述的 split()

  • str.rstrip([chars])

    返回原字符串的副本,移除其中的末尾字符。 chars 参数为指定要移除字符的字符串。 如果省略或为 None,则 chars 参数默认移除空格符。 实际上 chars 参数并非指定单个后缀;而是会移除参数值的所有组合:>>>>>> ' spacious '.rstrip() ' spacious' >>> 'mississippi'.rstrip('ipz') 'mississ'

  • str.split(sep=None, maxsplit=-1)

    返回一个由字符串内单词组成的列表,使用 sep 作为分隔字符串。 如果给出了 maxsplit,则最多进行 maxsplit 次拆分(因此,列表最多会有 maxsplit+1 个元素)。 如果 maxsplit 未指定或为 -1,则不限制拆分次数(进行所有可能的拆分)。如果给出了 sep,则连续的分隔符不会被组合在一起而是被视为分隔空字符串 (例如 '1,,2'.split(',') 将返回 ['1', '', '2'])。 sep 参数可能由多个字符组成 (例如 '1<>2<>3'.split('<>') 将返回 ['1', '2', '3'])。 使用指定的分隔符拆分空字符串将返回 ['']。例如:>>>>>> '1,2,3'.split(',') ['1', '2', '3'] >>> '1,2,3'.split(',', maxsplit=1) ['1', '2,3'] >>> '1,2,,3,'.split(',') ['1', '2', '', '3', ''] 如果 sep 未指定或为 None,则会应用另一种拆分算法:连续的空格会被视为单个分隔符,其结果将不包含开头或末尾的空字符串,如果字符串包含前缀或后缀空格的话。 因此,使用 None 拆分空字符串或仅包含空格的字符串将返回 []。例如:>>>>>> '1 2 3'.split() ['1', '2', '3'] >>> '1 2 3'.split(maxsplit=1) ['1', '2 3'] >>> ' 1 2 3 '.split() ['1', '2', '3']

  • str.splitlines([keepends])

    返回由原字符串中各行组成的列表,在行边界的位置拆分。 结果列表中不包含行边界,除非给出了 keepends且为真值。此方法会以下列行边界进行拆分。 特别地,行边界是 universal newlines 的一个超集。表示符描述\n换行\r回车\r\n回车 + 换行\v\x0b行制表符\f\x0c换表单\x1c文件分隔符\x1d组分隔符\x1e记录分隔符\x85下一行 (C1 控制码)\u2028行分隔符\u2029段分隔符在 3.2 版更改: \v\f 被添加到行边界列表例如:>>>>>> 'ab c\n\nde fg\rkl\r\n'.splitlines() ['ab c', '', 'de fg', 'kl'] >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] 不同于 split(),当给出了分隔字符串 sep 时,对于空字符串此方法将返回一个空列表,而末尾的换行不会令结果中增加额外的行:>>>>>> "".splitlines() [] >>> "One line\n".splitlines() ['One line'] 作为比较,split('\n') 的结果为:>>>>>> ''.split('\n') [''] >>> 'Two lines\n'.split('\n') ['Two lines', '']

  • str.startswith(prefix[, start[, end]])

    如果字符串以指定的 prefix 开始则返回 True,否则返回 False。 prefix 也可以为由多个供查找的前缀构成的元组。 如果有可选项 start,将从所指定位置开始检查。 如果有可选项 end,将在所指定位置停止比较。

  • str.strip([chars])

    返回原字符串的副本,移除其中的前导和末尾字符。 chars 参数为指定要移除字符的字符串。 如果省略或为 None,则 chars 参数默认移除空格符。 实际上 chars 参数并非指定单个前缀或后缀;而是会移除参数值的所有组合:>>>>>> ' spacious '.strip() 'spacious' >>> 'www.example.com'.strip('cmowz.') 'example' 最外侧的前导和末尾 chars 参数值将从字符串中移除。 开头端的字符的移除将在遇到一个未包含于 chars 所指定字符集的字符时停止。 类似的操作也将在结尾端发生。 例如:>>>>>> comment_string = '#....... Section 3.2.1 Issue #32 .......' >>> comment_string.strip('.#! ') 'Section 3.2.1 Issue #32'

  • str.swapcase()

    返回原字符串的副本,其中大写字符转换为小写,反之亦然。 请注意 s.swapcase().swapcase() == s 并不一定为真值。

  • str.title()

    返回原字符串的标题版本,其中每个单词第一个字母为大写,其余字母为小写。例如:>>>>>> 'Hello world'.title() 'Hello World' 该算法使用一种简单的与语言无关的定义,将连续的字母组合视为单词。 该定义在多数情况下都很有效,但它也意味着代表缩写形式与所有格的撇号也会成为单词边界,这可能导致不希望的结果:>>>>>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk" 可以使用正则表达式来构建针对撇号的特别处理:>>>>>> import re >>> def titlecase(s): ... return re.sub(r"[A-Za-z]+('[A-Za-z]+)?", ... lambda mo: mo.group(0).capitalize(), ... s) ... >>> titlecase("they're bill's friends.") "They're Bill's Friends."

  • str.translate(table)

    返回原字符串的副本,其中每个字符按给定的转换表进行映射。 转换表必须是一个使用 __getitem__() 来实现索引操作的对象,通常为 mappingsequence。 当以 Unicode 码位序号(整数)为索引时,转换表对象可以做以下任何一种操作:返回 Unicode 序号或字符串,将字符映射为一个或多个字符;返回 None,将字符从结果字符串中删除;或引发 LookupError 异常,将字符映射为其自身。你可以使用 str.maketrans() 基于不同格式的字符到字符映射来创建一个转换映射表。另请参阅 codecs 模块以了解定制字符映射的更灵活方式。

  • str.upper()

    返回原字符串的副本,其中所有区分大小写的字符 4 均转换为大写。 请注意如果 s 包含不区分大小写的字符或者如果结果字符的 Unicode 类别不是 "Lu" (Letter, uppercase) 而是 "Lt" (Letter, titlecase) 则 s.upper().isupper() 有可能为 False。所用转换大写算法的描述请参见 Unicode 标准的 3.13 节。

  • str.zfill(width)

    返回原字符串的副本,在左边填充 ASCII '0' 数码使其长度变为 width。 正负值前缀 ('+'/'-') 的处理方式是在正负符号 之后 填充而非在之前。 如果 width 小于等于 len(s) 则返回原字符串的副本。例如:>>>>>> "42".zfill(5) '00042' >>> "-42".zfill(5) '-0042'

8-2

查询文档:str.count(sub[, start[, end]])

print('banana'.count('a'))

8-3

Python
def is_palindrome(a):
    print(a[::-1] == a)
is_palindrome('acaa')

8-4

查看文档:

str.islower()

Return True if all cased characters in the string are lowercase and there is at least one cased character, False otherwise.

简单的说,全是小写return True,这个方法是用来检查字符串有没有大写字母的!

第一个遍历字符串,如果所有单个字母都不是大写,如果有,就直接返回True,可行。

第二个因为是在检查c这个字符串,必然为True,不可行。

第三个返回最后一个字母的True或者Flase,不可行。

第四个使用或,是上一个的改正版,可行。

第五个遇到大写直接returnFlase,不可行。

8-5

Python
def rotate_word(original_str, key):
    after_str = ''
    for a in original_str:
        n = ord(a) + 1
        after_str = after_str + chr(n)
    print(after_str)

rotate_word('python',1)

案例分析:文字游戏

doucument.readline(): 读入字符直到换行。

str.strip(): 用到过很多次了,去掉空白字符。

9.2 练习

9-1

Python
fin = open('words.txt')
for line in fin:
    word = line.strip()
    if len(word) > 20:
        print(word)

9-2

Python
fin = open('words.txt')
def has_no_e():
    n = 0
    n_without_e = 0

    for line in fin:
        word = line.strip()
        n = n + 1
        for alphabet in word:
            if alphabet == 'e':
                break
            else:
                n_without_e = n_without_e + 1
    print(n, n_without_e)

has_no_e()

9-3

我们将上面的函数重构得更方便移植。

Python
def avoids(alphabet, word):
    for letter in word:
        if letter == alphabet:
            return False
        else:
            return True

9-4

Python
def uses_only(permit_word, word):
    for letter in word:
        if letter not in permit_word:
            return False
        return True

9-5

Python
def use_all(permit_word, word):
    for letter in permit_word:
        if letter not in word:
            return False
        return True

9-7

Python
def cartalk(word):
    n = 0
    for i in range(len(word)):
        if len(word) - n < 6:
            break
        elif word[n]==word[n+1] and word[n+2]==word[n+3] and word[n+4]==word[n+5]:
            print(word)
        n = n + 1
cartalk('asdqeqssaaddasrf')

9-8

Python
def cartalk2():
    for i in range(899999):
        miles = 100000
        miles = miles + i
        # 将条件写开是是为了方便调试
        a = str(miles)[2::1] == str(miles)[:1:-1]
        b = str(miles+1)[1::1] == str(miles+1)[:0:-1]
        c = str(miles+2)[1:5:1] == str(miles+2)[4:0:-1]
        d = str(miles+3) == str(miles+3)[::-1]
        if a and b and c and d:
            print(miles)
cartalk2()

9-9

推荐了一种方法

str.zfill(=width)

返回原字符串的副本,在左边填充 ASCII '0' 数码使其长度变为 width。 正负值前缀 ('+'/'-') 的处理方式是在正负符号 之后 填充而非在之前。 如果 width 小于等于 len(s) 则返回原字符串的副本。

Python
from __future__ import print_function, division


def str_fill(i, n):
    """Returns i as a string with at least n digits.

    i: int
    n: int length

    returns: string
    """
    return str(i).zfill(n)


def are_reversed(i, j):
    """Checks if i and j are the reverse of each other.

    i: int
    j: int

    returns:bool
    """
    return str_fill(i, 2) == str_fill(j, 2)[::-1]


def num_instances(diff, flag=False):
    """Counts the number of palindromic ages.

    Returns the number of times the mother and daughter have
    palindromic ages in their lives, given the difference in age.

    diff: int difference in ages
    flag: bool, if True, prints the details
    """
    daughter = 0
    count = 0
    while True:
        mother = daughter + diff

        # assuming that mother and daughter don't have the same birthday,
        # they have two chances per year to have palindromic ages.
        if are_reversed(daughter, mother) or are_reversed(daughter, mother+1):
            count = count + 1
            if flag:
                print(daughter, mother)
        if mother > 120:
            break
        daughter = daughter + 1
    return count
    

def check_diffs():
    """Finds age differences that satisfy the problem.

    Enumerates the possible differences in age between mother
    and daughter, and for each difference, counts the number of times
    over their lives they will have ages that are the reverse of
    each other.
    """
    diff = 10
    while diff < 70:
        n = num_instances(diff)
        if n > 0:
            print(diff, n)
        diff = diff + 1

print('diff  #instances')
check_diffs()

print()
print('daughter  mother')
num_instances(18, True)
最后编辑于
文章链接: http://pheustal.com/2019/12-08/thinkpython6
本作品采用CC-BY-SA许可。