国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:六、字符串操作

這篇具有很好參考價(jià)值的文章主要介紹了Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:六、字符串操作。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

原文:https://automatetheboringstuff.com/2e/chapter6/

Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:六、字符串操作

文本是程序?qū)⑻幚淼淖畛R姷臄?shù)據(jù)形式之一。您已經(jīng)知道如何用+操作符將兩個(gè)字符串值連接在一起,但是您可以做得更多。您可以從字符串值中提取部分字符串,添加或刪除空格,將字母轉(zhuǎn)換為小寫或大寫,并檢查字符串的格式是否正確。您甚至可以編寫 Python 代碼來訪問剪貼板,以復(fù)制和粘貼文本。

在本章中,你將了解所有這些以及更多。然后,您將完成兩個(gè)不同的編程項(xiàng)目:一個(gè)存儲(chǔ)多個(gè)文本字符串的簡(jiǎn)單剪貼板和一個(gè)自動(dòng)完成格式化文本片段的枯燥工作的程序。

使用字符串

讓我們看看 Python 允許你在代碼中編寫、打印和訪問字符串的一些方法。

字符串字面值

用 Python 代碼鍵入字符串值相當(dāng)簡(jiǎn)單:它們以單引號(hào)開始和結(jié)束。但是你怎么能在字符串中使用引號(hào)呢?鍵入‘那是愛麗絲的貓?!粫?huì)起作用,因?yàn)?Python 認(rèn)為字符串在Alice之后結(jié)束,剩下的(s cat.')是無效的 Python 代碼。幸運(yùn)的是,有多種方法可以輸入字符串。

雙引號(hào)

字符串可以用雙引號(hào)開始和結(jié)束,就像用單引號(hào)一樣。使用雙引號(hào)的一個(gè)好處是字符串中可以有一個(gè)單引號(hào)字符。在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = "That is Alice's cat."

由于字符串以雙引號(hào)開始,Python 知道單引號(hào)是字符串的一部分,而不是標(biāo)記字符串的結(jié)尾。但是,如果需要在字符串中使用單引號(hào)和雙引號(hào),就需要使用轉(zhuǎn)義字符。

轉(zhuǎn)義字符

轉(zhuǎn)義字符讓你可以使用原本不可能放入字符串的字符。轉(zhuǎn)義字符由反斜杠(\)后跟要添加到字符串中的字符組成。(盡管由兩個(gè)字符組成,但它通常被稱為單個(gè)轉(zhuǎn)義字符。)例如,單引號(hào)的轉(zhuǎn)義字符是\'。您可以在以單引號(hào)開始和結(jié)束的字符串中使用它。要查看轉(zhuǎn)義字符如何工作,請(qǐng)?jiān)诮换ナ?Shell 中輸入以下內(nèi)容:

>>> spam = 'Say hi to Bob\'s mother.'

Python 知道,因?yàn)?code>Bob\'s中的單引號(hào)有一個(gè)反斜杠,所以它不是用來結(jié)束字符串值的單引號(hào)。轉(zhuǎn)義字符\'\"讓你分別在字符串中使用單引號(hào)和雙引號(hào)。

表 6-1 列出了您可以使用的轉(zhuǎn)義字符。

表 6-1: 轉(zhuǎn)義字符

轉(zhuǎn)義字符 打印為
\' 單引號(hào)
\" 雙引號(hào)
\t 制表符
\n 換行(換行符)
\\ 反斜線符號(hào)

在交互式 Shell 中輸入以下內(nèi)容:

>>> print("Hello there!\nHow are you?\nI\'m doing fine.")
Hello there!
How are you?
I'm doing fine.
原始字符串

您可以在字符串的開始引號(hào)前放置一個(gè)r,使其成為原始字符串。原始字符串完全忽略所有轉(zhuǎn)義字符并打印字符串中出現(xiàn)的任何反斜杠。例如,在交互式 Shell 中輸入以下內(nèi)容:

>>> print(r'That is Carol\'s cat.')
That is Carol\'s cat.

因?yàn)檫@是一個(gè)原始字符串,Python 將反斜杠視為字符串的一部分,而不是轉(zhuǎn)義字符的開始。如果您鍵入包含許多反斜杠的字符串值,例如用于 Windows 文件路徑的字符串,如r'C:\Users\Al\Desktop'或下一章中描述的正則表達(dá)式,原始字符串會(huì)很有幫助。

帶三重引號(hào)的多行字符串

雖然您可以使用\n轉(zhuǎn)義字符將換行符放入字符串中,但使用多行字符串通常更容易。Python 中的多行字符串以三個(gè)單引號(hào)或三個(gè)雙引號(hào)開始和結(jié)束?!叭匾?hào)”之間的任何引號(hào)、制表符或換行符都被視為字符串的一部分。Python 的塊縮進(jìn)規(guī)則不適用于多行字符串中的行。

打開文件編輯器,編寫以下內(nèi)容:

print('''Dear Alice,
Eve's cat has been arrested for catnapping, cat burglary, and extortion.
Sincerely,
Bob''')

將該程序保存為catnapping.py并運(yùn)行。輸出將如下所示:

Dear Alice,
Eve's cat has been arrested for catnapping, cat burglary, and extortion.
Sincerely,
Bob

注意Eve's中的單引號(hào)字符不需要轉(zhuǎn)義。在多行字符串中,轉(zhuǎn)義單引號(hào)和雙引號(hào)是可選的。下面的print()調(diào)用將打印相同的文本,但不使用多行字符串:

print('Dear Alice,\n\nEve\'s cat has been arrested for catnapping, cat
burglary, and extortion.\n\nSincerely,\nBob')
多行注釋

雖然散列字符(#)標(biāo)記了該行剩余部分的注釋的開始,但是多行字符串通常用于跨多行的注釋。以下是完全有效的 Python 代碼:

"""This is a test Python program.
Written by Al Sweigart al@inventwithpython.com
This program was designed for Python 3, not Python 2.
"""
def spam():
    """This is a multiline comment to help
    explain what the spam() function does."""
    print('Hello!')
索引和切片字符串

字符串和列表一樣使用索引和切片。您可以將字符串'Hello, world!'視為一個(gè)列表,并將字符串中的每個(gè)字符視為一個(gè)具有相應(yīng)索引的項(xiàng)。

“你好,我好,我好!”
T1 0 1 2 3 4 5 6 7 8 9 10 11 12

空格和感嘆號(hào)包含在字符數(shù)中,所以'Hello, world!'是 13 個(gè)字符長(zhǎng),從索引 0 處的H到索引 12 處的!。

在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = 'Hello, world!'
>>> spam[0]
'H'
>>> spam[4]
'o'
>>> spam[-1]
'!'
>>> spam[0:5]
'Hello'
>>> spam[:5]
'Hello'
>>> spam[7:]
'world!'

如果你指定了一個(gè)索引,你將得到字符串中該位置的字符。如果指定從一個(gè)索引到另一個(gè)索引的范圍,則包括起始索引,不包括結(jié)束索引。這就是為什么,如果spam'Hello, world!',spam[0:5]'Hello'。從spam[0:5]得到的子串將包括從spam[0]spam[4]的所有內(nèi)容,去掉索引 5 處的逗號(hào)和索引 6 處的空格。這類似于range(5)如何導(dǎo)致for循環(huán)迭代到5,但不包括5。

請(qǐng)注意,對(duì)字符串進(jìn)行切片不會(huì)修改原始字符串。您可以在單獨(dú)的變量中捕獲一個(gè)變量的切片。嘗試在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = 'Hello, world!'
>>> fizz = spam[0:5]
>>> fizz
'Hello'

通過將得到的子串切片并存儲(chǔ)在另一個(gè)變量中,您可以方便地快速、輕松地訪問整個(gè)字符串和子串。

字符串與innot運(yùn)算符

與列表值一樣,innot in操作符也可以用于字符串。使用innot in連接兩個(gè)字符串的表達(dá)式將求值為布爾型TrueFalse。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello' in 'Hello, World'
True
>>> 'Hello' in 'Hello'
True
>>> 'HELLO' in 'Hello, World'
False
>>> '' in 'spam'
True
>>> 'cats' not in 'cats and dogs'
False

這些表達(dá)式測(cè)試是否可以在第二個(gè)字符串中找到第一個(gè)字符串(精確字符串,區(qū)分大小寫)。

將字符串放入其他字符串中

將字符串放入其他字符串中是編程中的常見操作。到目前為止,我們已經(jīng)使用了+操作符和字符串連接來完成這項(xiàng)工作:

>>> name = 'Al'
>>> age = 4000
>>> 'Hello, my name is ' + name + '. I am ' + str(age) + ' years old.'
'Hello, my name is Al. I am 4000 years old.'

然而,這需要大量繁瑣的打字工作。一種更簡(jiǎn)單的方法是使用字符串插值,其中字符串中的%s操作符作為一個(gè)標(biāo)記,將被字符串后面的值替換。字符串插值的一個(gè)好處是不需要調(diào)用str()來將值轉(zhuǎn)換成字符串。在交互式 Shell 中輸入以下內(nèi)容:

>>> name = 'Al'
>>> age = 4000
>>> 'My name is %s. I am %s years old.' % (name, age)
'My name is Al. I am 4000 years old.'

Python 3.6 引入了f-strings,除了用大括號(hào)代替了%s,表達(dá)式直接放在大括號(hào)里面,與字符串插值類似。像原始字符串一樣,F(xiàn) 字符串在起始引號(hào)前有一個(gè)f前綴。在交互式 Shell 中輸入以下內(nèi)容:

>>> name = 'Al'
>>> age = 4000
>>> f'My name is {name}. Next year I will be {age + 1}.'
'My name is Al. Next year I will be 4001.'

記得包括f前綴;否則,大括號(hào)及其內(nèi)容將成為字符串值的一部分:

>>> 'My name is {name}. Next year I will be {age + 1}.'
'My name is {name}. Next year I will be {age + 1}.'

有用的字符串方法

一些字符串方法分析字符串或創(chuàng)建轉(zhuǎn)換后的字符串值。本節(jié)描述了您最常使用的方法。

upper()lower()、isupper()islower()方法

upper()lower()字符串方法返回一個(gè)新的字符串,其中原始字符串中的所有字母已經(jīng)分別轉(zhuǎn)換為大寫或小寫。字符串中的非字母字符保持不變。在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = 'Hello, world!'
>>> spam = spam.upper()
>>> spam
'HELLO, WORLD!'
>>> spam = spam.lower()
>>> spam
'hello, world!'

請(qǐng)注意,這些方法不會(huì)更改字符串本身,而是返回新的字符串值。如果你想改變?cè)瓉淼淖址?,你必須調(diào)用字符串上的upper()lower(),然后把新的字符串賦給原來存儲(chǔ)的變量。這就是為什么你必須使用spam = spam.upper()來改變spam中的字符串,而不是簡(jiǎn)單地使用spam.upper()。(這就像變量eggs包含值10。寫eggs + 3不會(huì)改變eggs的值,但eggs = eggs + 3會(huì)。)

如果您需要進(jìn)行不區(qū)分大小寫的比較,那么upper()lower()方法會(huì)很有幫助。例如,字符串'great''GREat'彼此不相等。但是在下面的小程序中,用戶鍵入Great、GREAT還是grEAT都無關(guān)緊要,因?yàn)樽址紫缺晦D(zhuǎn)換成小寫。

print('How are you?')
feeling = input()
if feeling.lower() == 'great':
    print('I feel great too.')
else:
    print('I hope the rest of your day is good.')

當(dāng)你運(yùn)行這個(gè)程序時(shí),問題被顯示出來,在great上輸入一個(gè)變量,比如GREat,仍然會(huì)給出輸出I feel great too。向程序中添加代碼來處理用戶輸入中的變化或錯(cuò)誤,例如大小寫不一致,將使程序更容易使用,并且不太可能失敗。

How are you?
GREat
I feel great too.

您可以在autbor.com/convertlowercase查看該程序的執(zhí)行情況。如果字符串至少有一個(gè)字母并且所有字母都是大寫或小寫,那么isupper()islower()方法將返回一個(gè)布爾值True。否則,該方法返回False。在交互式 Shell 中輸入以下內(nèi)容,并注意每個(gè)方法調(diào)用返回的內(nèi)容:

>>> spam = 'Hello, world!'
>>> spam.islower()
False
>>> spam.isupper()
False
>>> 'HELLO'.isupper()
True
>>> 'abc12345'.islower()
True
>>> '12345'.islower()
False
>>> '12345'.isupper()
False

因?yàn)?code>upper()和lower()字符串方法本身返回字符串,所以您也可以在返回字符串值的字符串方法上調(diào)用它們。這樣做的表達(dá)式看起來像一個(gè)方法調(diào)用鏈。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello'.upper()
'HELLO'
>>> 'Hello'.upper().lower()
'hello'
>>> 'Hello'.upper().lower().upper()
'HELLO'
>>> 'HELLO'.lower()
'hello'
>>> 'HELLO'.lower().islower()
True
isX方法

除了islower()isupper()之外,還有其他幾個(gè)以單詞is開頭的字符串方法。這些方法返回一個(gè)描述字符串性質(zhì)的布爾值。下面是一些常見的is X 串音方法:

如果字符串僅由字母組成且不為空,則isalpha()返回True

如果字符串僅由字母和數(shù)字組成并且不為空,則isalnum()返回True

如果字符串僅由數(shù)字字符組成且不為空,則isdecimal()返回True

如果字符串僅由空格、制表符和換行符組成并且不為空,則isspace()返回True

如果字符串只包含以大寫字母開頭、后跟小寫字母的單詞,則istitle()返回True

在交互式 Shell 中輸入以下內(nèi)容:

>>> 'hello'.isalpha()
True
>>> 'hello123'.isalpha()
False
>>> 'hello123'.isalnum()
True
>>> 'hello'.isalnum()
True
>>> '123'.isdecimal()
True
>>> '    '.isspace()
True
>>> 'This Is Title Case'.istitle()
True
>>> 'This Is Title Case 123'.istitle()
True
>>> 'This Is not Title Case'.istitle()
False
>>> 'This Is NOT Title Case Either'.istitle()
False

當(dāng)您需要驗(yàn)證用戶輸入時(shí),is X() 字符串方法非常有用。例如,下面的程序反復(fù)詢問用戶的年齡和密碼,直到他們提供有效的輸入。打開一個(gè)新的文件編輯器窗口,進(jìn)入這個(gè)程序,保存為validateInput.py :

while True:
    print('Enter your age:')
    age = input()
    if age.isdecimal():
        break
    print('Please enter a number for your age.')
while True:
    print('Select a new password (letters and numbers only):')
    password = input()
    if password.isalnum():
        break
    print('Passwords can only have letters and numbers.')

在第一個(gè)while循環(huán)中,我們?cè)儐栍脩舻哪挲g,并將他們的輸入存儲(chǔ)在age中。如果age是一個(gè)有效的(十進(jìn)制)值,我們就跳出第一個(gè)while循環(huán),進(jìn)入第二個(gè)循環(huán),要求輸入密碼。否則,我們會(huì)通知用戶需要輸入一個(gè)數(shù)字,并再次要求他們輸入年齡。在第二個(gè)while循環(huán)中,我們要求輸入密碼,將用戶的輸入存儲(chǔ)在password中,如果輸入是字母數(shù)字,就退出循環(huán)。如果不是,我們不滿意,所以我們告訴用戶密碼需要是字母數(shù)字,并再次要求他們輸入密碼。

運(yùn)行時(shí),程序的輸出看起來像這樣:

Enter your age:
forty two
Please enter a number for your age.
Enter your age:
42
Select a new password (letters and numbers only):
secr3t!
Passwords can only have letters and numbers.
Select a new password (letters and numbers only):
secr3t

您可以在autbor.com/validateinput查看該程序的執(zhí)行情況。在變量上調(diào)用isdecimal()isalnum(),我們能夠測(cè)試存儲(chǔ)在這些變量中的值是否是十進(jìn)制的,字母數(shù)字的。這里,這些測(cè)試幫助我們拒絕輸入forty two但接受42,拒絕secr3t!但接受secr3t

startswith()endswith()方法

如果被調(diào)用的字符串值以傳遞給方法的字符串開始或結(jié)束,則startswith()endswith()方法返回True;否則,它們返回False。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello, world!'.startswith('Hello')
True
>>> 'Hello, world!'.endswith('world!')
True
>>> 'abc123'.startswith('abcdef')
False
>>> 'abc123'.endswith('12')
False
>>> 'Hello, world!'.startswith('Hello, world!')
True
>>> 'Hello, world!'.endswith('Hello, world!')
True

如果您只需要檢查字符串的第一部分或最后一部分是否等于另一個(gè)字符串,而不是整個(gè)字符串,這些方法是== equals 運(yùn)算符的有用替代方法。

使用join()split()方法

當(dāng)您有一個(gè)需要連接成一個(gè)字符串值的字符串列表時(shí),join()方法很有用。在一個(gè)字符串上調(diào)用join()方法,傳遞一個(gè)字符串列表,然后返回一個(gè)字符串。返回的字符串是傳入列表中每個(gè)字符串的連接。例如,在交互式 Shell 中輸入以下內(nèi)容:

>>> ', '.join(['cats', 'rats', 'bats'])
'cats, rats, bats'
>>> ' '.join(['My', 'name', 'is', 'Simon'])
'My name is Simon'
>>> 'ABC'.join(['My', 'name', 'is', 'Simon'])
'MyABCnameABCisABCSimon'

請(qǐng)注意,調(diào)用的字符串join()被插入到列表參數(shù)的每個(gè)字符串之間。例如,當(dāng)在', '字符串上調(diào)用join(['cats', 'rats', 'bats'])時(shí),返回的字符串是'cats, rats, bats'。

記住join()是在一個(gè)字符串值上被調(diào)用的,并被傳遞一個(gè)列表值。(很容易不小心叫反了。)方法split()的作用正好相反:它對(duì)一個(gè)字符串值進(jìn)行調(diào)用,并返回一個(gè)字符串列表。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'My name is Simon'.split()
['My', 'name', 'is', 'Simon']

默認(rèn)情況下,字符串'My name is Simon'會(huì)在發(fā)現(xiàn)空格、制表符或換行符等空白字符的地方被拆分。這些空白字符不包括在返回列表的字符串中。您可以向split()方法傳遞一個(gè)分隔符字符串來指定一個(gè)不同的分割字符串。例如,在交互式 Shell 中輸入以下內(nèi)容:

>>> 'MyABCnameABCisABCSimon'.split('ABC')
['My', 'name', 'is', 'Simon']
>>> 'My name is Simon'.split('m')
['My na', 'e is Si', 'on']

split()的一個(gè)常見用法是沿著換行符拆分多行字符串。在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = '''Dear Alice,
How have you been? I am fine.
There is a container in the fridge
that is labeled "Milk Experiment."
Please do not drink it.
Sincerely,
Bob'''
>>> spam.split('\n')
['Dear Alice,', 'How have you been? I am fine.', 'There is a container in the 
fridge', 'that is labeled "Milk Experiment."', '', 'Please do not drink it.', 
'Sincerely,', 'Bob']

傳遞參數(shù)'\n'split()讓我們沿著新行分割存儲(chǔ)在spam中的多行字符串,并返回一個(gè)列表,其中每一項(xiàng)對(duì)應(yīng)于字符串的一行。

partition()方法拆分字符串

partition()字符串方法可以將一個(gè)字符串拆分成分隔符字符串前后的文本。此方法在調(diào)用它的字符串中搜索它所傳遞的分隔符字符串,并為beforeseparatorafter子字符串返回一個(gè)由三個(gè)子字符串組成的元組。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello, world!'.partition('w')
('Hello, ', 'w', 'orld!')
>>> 'Hello, world!'.partition('world')
('Hello, ', 'world', '!')

如果您傳遞給partition()的分隔符字符串在partition()調(diào)用的字符串中出現(xiàn)多次,該方法只在第一次出現(xiàn)時(shí)拆分字符串:

>>> 'Hello, world!'.partition('o')
('Hell', 'o', ', world!')

如果找不到分隔符字符串,則元組中返回的第一個(gè)字符串將是整個(gè)字符串,其他兩個(gè)字符串將為空:

>>> 'Hello, world!'.partition('XYZ')
('Hello, world!', '', '')

您可以使用多重賦值技巧將三個(gè)返回的字符串賦給三個(gè)變量:

>>> before, sep, after = 'Hello, world!'.partition(' ')
>>> before
'Hello,'
>>> after
'world!'

無論何時(shí),當(dāng)您需要某個(gè)特定分隔符字符串之前、之后的部分時(shí),partition()方法對(duì)于拆分字符串非常有用。

rjust()、just()center()方法調(diào)整文本

rjust()ljust()字符串方法返回它們被調(diào)用的字符串的填充版本,其中插入空格以對(duì)齊文本。這兩種方法的第一個(gè)參數(shù)是兩端對(duì)齊的字符串的整數(shù)長(zhǎng)度。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello'.rjust(10)
'     Hello'
>>> 'Hello'.rjust(20)
'              Hello'
>>> 'Hello, World'.rjust(20)
'         Hello, World'
>>> 'Hello'.ljust(10)
'Hello     '

'Hello'.rjust(10)表示我們想要右對(duì)齊總長(zhǎng)度為10的字符串中的'Hello'。'Hello'是五個(gè)字符,所以它的左邊會(huì)增加五個(gè)空格,這樣我們得到一個(gè)由 10 個(gè)字符組成的字符串,其中'Hello'右對(duì)齊。

可選的第二個(gè)參數(shù)rjust()ljust()將指定一個(gè)填充字符而不是一個(gè)空格字符。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello'.rjust(20, '*')
'***************Hello'
>>> 'Hello'.ljust(20, '-')
'Hello---------------'

center()字符串方法的工作方式類似于ljust()rjust(),但是它將文本居中,而不是將其向左或向右對(duì)齊。在交互式 Shell 中輸入以下內(nèi)容:

>>> 'Hello'.center(20)
'       Hello        '
>>> 'Hello'.center(20, '=')
'=======Hello========'

當(dāng)您需要打印具有正確間距的表格數(shù)據(jù)時(shí),這些方法特別有用。打開一個(gè)新的文件編輯器窗口,輸入以下代碼,保存為pickTable.py:

def printPicnic(itemsDict, leftWidth, rightWidth):
    print('PICNIC ITEMS'.center(leftWidth + rightWidth, '-'))
    for k, v in itemsDict.items():
        print(k.ljust(leftWidth, '.') + str(v).rjust(rightWidth))
picnicItems = {'sandwiches': 4, 'apples': 12, 'cups': 4, 'cookies': 8000}
printPicnic(picnicItems, 12, 5)
printPicnic(picnicItems, 20, 6)

您可以在autbor.com/picnictable查看該程序的執(zhí)行情況。在這個(gè)程序中,我們定義了一個(gè)printPicnic()方法,它將接收一個(gè)信息字典,并使用center()ljust()rjust()以整齊排列的表格格式顯示信息。

我們將傳遞給printPicnic()的字典是picnicItems。在picnicItems,我們有 4 個(gè)三明治、12 個(gè)蘋果、4 個(gè)杯子和 8000 塊餅干。我們希望將這些信息組織成兩列,左邊是商品名稱,右邊是數(shù)量。

要做到這一點(diǎn),我們需要決定左右欄的寬度。連同我們的字典,我們將把這些值傳遞給printPicnic()

printPicnic()函數(shù)接收一個(gè)字典,一個(gè)leftWidth用于表格的左列,一個(gè)rightWidth用于右列。它在表的中央打印一個(gè)標(biāo)題PICNIC ITEMS。然后,它遍歷字典,在一行上打印每個(gè)鍵-值對(duì),鍵靠左對(duì)齊并用句點(diǎn)填充,值靠右對(duì)齊并用空格填充。

在定義了printPicnic()之后,我們定義了字典picnicItems并調(diào)用了printPicnic()兩次,為左右表列傳遞了不同的寬度。

當(dāng)您運(yùn)行這個(gè)程序時(shí),野餐項(xiàng)目會(huì)顯示兩次。第一次左欄寬 12 個(gè)字符,右欄寬 5 個(gè)字符。第二次分別是 20 和 6 個(gè)字符寬。

---PICNIC ITEMS--
sandwiches..    4
apples......   12
cups........    4
cookies..... 8000
-------PICNIC ITEMS-------
sandwiches..........     4
apples..............    12
cups................     4
cookies.............  8000

使用rjust()、ljust()center()可以確保字符串整齊對(duì)齊,即使您不確定字符串有多少個(gè)字符長(zhǎng)。

strip()、rstrip()lstrip()方法去除空白

有時(shí),您可能希望去除字符串左側(cè)、右側(cè)或兩側(cè)的空白字符(空格、制表符和換行符)。字符串方法將返回一個(gè)開頭或結(jié)尾沒有任何空白字符的新字符串。lstrip()rstrip()方法將分別刪除左端和右端的空白字符。在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = '    Hello, World    '
>>> spam.strip()
'Hello, World'
>>> spam.lstrip()
'Hello, World    '
>>> spam.rstrip()
'    Hello, World'

或者,字符串參數(shù)將指定應(yīng)該去除末尾的哪些字符。在交互式 Shell 中輸入以下內(nèi)容:

>>> spam = 'SpamSpamBaconSpamEggsSpamSpam'
>>> spam.strip('ampS')
'BaconSpamEggs'

傳遞strip()參數(shù)'ampS'將告訴它從存儲(chǔ)在spam中的字符串末尾刪除出現(xiàn)的am、p和大寫S。傳遞給strip()的字符串中字符的順序無關(guān)緊要:strip('ampS')將做與strip('mapS')strip('Spam')相同的事情。

ord()和chr()函數(shù)與字符的數(shù)值

計(jì)算機(jī)將信息存儲(chǔ)為字節(jié)——二進(jìn)制數(shù)的字符串,這意味著我們需要能夠?qū)⑽谋巨D(zhuǎn)換為數(shù)字。因此,每個(gè)文本字符都有一個(gè)對(duì)應(yīng)的數(shù)值,稱為 Unicode 碼位。例如,'A'的數(shù)字碼位為65,'4'的數(shù)字碼位為52,'!'的數(shù)字碼位為33。您可以使用ord()函數(shù)獲取單字符字符串的碼位,使用chr()函數(shù)獲取整數(shù)碼位的單字符字符串。在交互式 Shell 中輸入以下內(nèi)容:

>>> ord('A')
65
>>> ord('4')
52
>>> ord('!')
33
>>> chr(65)
'A'

當(dāng)您需要排序字符或數(shù)學(xué)運(yùn)算時(shí),這些函數(shù)非常有用:

>>> ord('B')
66
>>> ord('A') < ord('B')
True
>>> chr(ord('A'))
'A'
>>> chr(ord('A') + 1)
'B'

關(guān)于 Unicode 和代碼點(diǎn)還有更多內(nèi)容,但是這些細(xì)節(jié)已經(jīng)超出了本書的范圍。如果你想了解更多,我推薦你觀看內(nèi)德·巴徹爾德 2012 年的 PyCon 演講,“實(shí)用 Unicode,或者,我如何停止痛苦?”在youtu.be/sgHbC6udIqc上。

使用pyperclip模塊復(fù)制和粘貼字符串

pyperclip模塊有copy()paste()函數(shù),可以向你的電腦剪貼板發(fā)送文本,也可以從剪貼板接收文本。將程序的輸出發(fā)送到剪貼板會(huì)使它更容易粘貼到電子郵件、文字處理器或其他軟件中。

在Mu之外運(yùn)行 PYTHON 腳本

到目前為止,您已經(jīng)使用 Mu 中的交互式 Shell 和文件編輯器運(yùn)行了 Python 腳本。然而,你不會(huì)想每次運(yùn)行腳本時(shí)都要經(jīng)歷打開 Mu 和 Python 腳本的不便。幸運(yùn)的是,您可以設(shè)置一些快捷方式來簡(jiǎn)化 Python 腳本的運(yùn)行。對(duì)于 Windows、MacOS 和 Linux,這些步驟略有不同,但是每個(gè)步驟都在附錄 B 中進(jìn)行了描述。轉(zhuǎn)到附錄 B 來學(xué)習(xí)如何方便地運(yùn)行你的 Python 腳本,并能夠向它們傳遞命令行參數(shù)。(您將無法使用 Mu 向您的程序傳遞命令行參數(shù)。)

Python 中沒有pyperclip模塊。要安裝它,請(qǐng)遵循附錄 A 中安裝第三方模塊的說明。安裝pyperclip后,在交互 Shell 中輸入以下內(nèi)容:

>>> import pyperclip
>>> pyperclip.copy('Hello, world!')
>>> pyperclip.paste()
'Hello, world!'

當(dāng)然,如果程序之外的東西改變了剪貼板的內(nèi)容,paste()函數(shù)將返回它。例如,如果我將這句話復(fù)制到剪貼板,然后調(diào)用paste(),它會(huì)是這樣的:

>>> pyperclip.paste()
'For example, if I copied this sentence to the clipboard and then called
paste(), it would look like this:'

項(xiàng)目:多剪貼板自動(dòng)消息

如果你回復(fù)了大量措辭相似的郵件,你可能不得不做大量的重復(fù)輸入。也許你用這些短語保存了一個(gè)文本文檔,這樣你就可以用剪貼板方便地復(fù)制和粘貼它們。但是你的剪貼板一次只能存儲(chǔ)一條消息,這不是很方便。讓我們用一個(gè)存儲(chǔ)多個(gè)短語的程序來簡(jiǎn)化這個(gè)過程。

第一步:程序設(shè)計(jì)和數(shù)據(jù)結(jié)構(gòu)

您希望能夠用一個(gè)簡(jiǎn)短的關(guān)鍵短語作為命令行參數(shù)來運(yùn)行這個(gè)程序,例如,同意忙碌。與該關(guān)鍵短語相關(guān)聯(lián)的消息將被復(fù)制到剪貼板,以便用戶可以將其粘貼到電子郵件中。這樣,用戶不必重新輸入就可以獲得長(zhǎng)而詳細(xì)的消息。

章節(jié)項(xiàng)目

這是本書的第一個(gè)“章節(jié)項(xiàng)目”。從現(xiàn)在開始,每章都將有展示本章所涵蓋概念的項(xiàng)目。這些項(xiàng)目以一種風(fēng)格編寫,將您從一個(gè)空白的文件編輯器窗口帶到一個(gè)完整的工作程序。就像交互式 Shell 示例一樣,不要只閱讀項(xiàng)目部分——在您的計(jì)算機(jī)上跟著做!

打開一個(gè)新的文件編輯器窗口,將程序保存為mclip.py。你需要用一行#! ( shebang )來開始這個(gè)程序(見附錄 B ),還應(yīng)該寫一個(gè)簡(jiǎn)短描述這個(gè)程序的注釋。因?yàn)槟M麑⒚慷挝谋九c其關(guān)鍵短語相關(guān)聯(lián),所以可以將它們作為字符串存儲(chǔ)在字典中。字典將是組織你的關(guān)鍵短語和文本的數(shù)據(jù)結(jié)構(gòu)。讓您的程序看起來像下面這樣:

#! python3
# mclip.py - A multi-clipboard program.
TEXT = {'agree': """Yes, I agree. That sounds fine to me.""",
        'busy': """Sorry, can we do this later this week or next week?""",
        'upsell': """Would you consider making this a monthly donation?"""}
第二步:處理命令行參數(shù)

命令行參數(shù)將存儲(chǔ)在變量sys.argv中。(關(guān)于如何在你的程序中使用命令行參數(shù)的更多信息,請(qǐng)參見附錄 B 。)列表中的第一項(xiàng)應(yīng)該總是包含程序文件名('mclip.py')的字符串,第二項(xiàng)應(yīng)該是第一個(gè)命令行參數(shù)。對(duì)于這個(gè)程序,這個(gè)參數(shù)是你想要的信息的關(guān)鍵短語。因?yàn)槊钚袇?shù)是強(qiáng)制的,所以如果用戶忘記添加它(也就是說,如果sys.argv列表中的值少于兩個(gè)),您會(huì)向用戶顯示一條用法消息。讓您的程序看起來像下面這樣:

#! python3
# mclip.py - A multi-clipboard program.
TEXT = {'agree': """Yes, I agree. That sounds fine to me.""",
        'busy': """Sorry, can we do this later this week or next week?""",
        'upsell': """Would you consider making this a monthly donation?"""}
import sys
if len(sys.argv) < 2:
    print('Usage: python mclip.py [keyphrase] - copy phrase text')
    sys.exit()
keyphrase = sys.argv[1]    # first command line arg is the keyphrase
第三步:復(fù)制正確詞組

現(xiàn)在關(guān)鍵短語作為字符串存儲(chǔ)在變量keyphrase中,您需要查看它是否作為一個(gè)鍵存在于TEXT字典中。如果是這樣,您需要使用pyperclip.copy()將鍵值復(fù)制到剪貼板。(因?yàn)槟谑褂?code>pyperclip模塊,所以您需要導(dǎo)入它。)注意,實(shí)際上并不需要這個(gè)keyphrase變量;你可以在這個(gè)程序中使用keyphrase的任何地方使用sys.argv[1]。但是一個(gè)名為keyphrase的變量比類似于sys.argv[1]的神秘東西更具可讀性。

讓您的程序看起來像下面這樣:

#! python3
# mclip.py - A multi-clipboard program.
TEXT = {'agree': """Yes, I agree. That sounds fine to me.""",
        'busy': """Sorry, can we do this later this week or next week?""",
        'upsell': """Would you consider making this a monthly donation?"""}
import sys, pyperclip
if len(sys.argv) < 2:
    print('Usage: py mclip.py [keyphrase] - copy phrase text')
    sys.exit()
keyphrase = sys.argv[1]    # first command line arg is the keyphrase
if keyphrase in TEXT:
    pyperclip.copy(TEXT[keyphrase])
    print('Text for ' + keyphrase + ' copied to clipboard.')
else:
    print('There is no text for ' + keyphrase)

這個(gè)新代碼在TEXT字典中查找關(guān)鍵短語。如果關(guān)鍵短語是字典中的一個(gè)鍵,我們獲得對(duì)應(yīng)于該鍵的值,將其復(fù)制到剪貼板,并打印一條消息,說明我們復(fù)制了該值。否則,我們會(huì)打印一條消息,說明沒有該名稱的關(guān)鍵短語。

這是完整的劇本。使用附錄 B 中的指令輕松啟動(dòng)命令行程序,你現(xiàn)在有了一個(gè)快速復(fù)制信息到剪貼板的方法。每當(dāng)您想用新消息更新程序時(shí),您必須修改源代碼中的TEXT字典值。

在 Windows 上,您可以創(chuàng)建一個(gè)批處理文件,用WIN-R運(yùn)行窗口運(yùn)行這個(gè)程序。(關(guān)于批處理文件的更多信息,參見附錄 B 。)在文件編輯器中輸入以下內(nèi)容,并將該文件作為mclip.bat保存在C:\Windows文件夾中:

@py.exe C:\path_to_file\mclip.py %*
@pause

創(chuàng)建了這個(gè)批處理文件后,在 Windows 上運(yùn)行多剪貼板程序只需按下WIN-R并鍵入mclip關(guān)鍵詞即可。

項(xiàng)目:向維基標(biāo)記添加項(xiàng)目符號(hào)

編輯維基百科文章時(shí),你可以創(chuàng)建一個(gè)項(xiàng)目符號(hào)列表,將每個(gè)列表項(xiàng)放在自己的行上,并在前面加一個(gè)星號(hào)。但是假設(shè)你有一個(gè)很大的列表,你想添加要點(diǎn)。你可以在每一行的開頭一個(gè)接一個(gè)地輸入這些星號(hào)。或者您可以使用一個(gè)簡(jiǎn)短的 Python 腳本來自動(dòng)完成這項(xiàng)任務(wù)。

bulletPointAdder.py腳本將從剪貼板獲取文本,在每一行的開頭添加一個(gè)星號(hào)和空格,然后將這個(gè)新文本粘貼到剪貼板。例如,如果我將以下文本(針對(duì)維基百科文章“列表列表列表”)復(fù)制到剪貼板:

Lists of animals
Lists of aquarium life
Lists of biologists by author abbreviation
Lists of cultivars

然后運(yùn)行bulletPointAdder.py程序,剪貼板將包含以下內(nèi)容:

* Lists of animals
* Lists of aquarium life
* Lists of biologists by author abbreviation
* Lists of cultivars

這個(gè)帶星號(hào)前綴的文本可以作為項(xiàng)目符號(hào)列表粘貼到維基百科的文章中。

第一步:從剪貼板復(fù)制粘貼

您希望bulletPointAdder.py程序執(zhí)行以下操作:

  1. 從剪貼板粘貼文本。
  2. 做點(diǎn)什么。
  3. 將新文本復(fù)制到剪貼板。

第二步有點(diǎn)復(fù)雜,但是第一步和第三步非常簡(jiǎn)單:它們只涉及到pyperclip.copy()pyperclip.paste()函數(shù)?,F(xiàn)在,讓我們只編寫程序的第 1 步和第 3 步。輸入以下內(nèi)容,將程序保存為bulletPointAdder.py :

#! python3
# bulletPointAdder.py - Adds Wikipedia bullet points to the start
# of each line of text on the clipboard.
import pyperclip
text = pyperclip.paste()
# TODO: Separate lines and add stars.
pyperclip.copy(text)

TODO注釋提醒您最終應(yīng)該完成程序的這一部分。下一步是實(shí)際實(shí)現(xiàn)程序的這一部分。

第二步:把文字的行分開,加上星號(hào)

對(duì)pyperclip.paste()的調(diào)用將剪貼板上的所有文本作為一個(gè)大字符串返回。如果我們使用“列表的列表的列表”示例,存儲(chǔ)在text中的字符串將如下所示:

'Lists of animals\nLists of aquarium life\nLists of biologists by author
abbreviation\nLists of cultivars'

該字符串中的\n換行符導(dǎo)致它在從剪貼板打印或粘貼時(shí)顯示為多行。在這個(gè)字符串值中有許多“行”。您需要在每一行的開頭添加一個(gè)星號(hào)。

您可以編寫代碼來搜索字符串中的每個(gè)\n換行符,然后在其后添加星號(hào)。但是使用split()方法返回一個(gè)字符串列表會(huì)更容易,原始字符串中的每一行都有一個(gè)字符串,然后在列表中的每個(gè)字符串前面加上星號(hào)。

讓您的程序看起來像下面這樣:

#! python3
# bulletPointAdder.py - Adds Wikipedia bullet points to the start
# of each line of text on the clipboard.
import pyperclip
text = pyperclip.paste()
# Separate lines and add stars.
lines = text.split('\n')
for i in range(len(lines)):    # loop through all indexes in the "lines" list
    lines[i] = '* ' + lines[i] # add star to each string in "lines" list
pyperclip.copy(text)

我們沿著文本的新行分割文本,得到一個(gè)列表,列表中的每一項(xiàng)都是文本的一行。我們將列表存儲(chǔ)在lines中,然后遍歷lines中的項(xiàng)目。對(duì)于每一行,我們?cè)谛惺滋砑右粋€(gè)星號(hào)和一個(gè)空格?,F(xiàn)在lines中的每個(gè)字符串都以一個(gè)星號(hào)開始。

第三步:添加修改后的行

lines列表現(xiàn)在包含以星號(hào)開始的修改行。但是pyperclip.copy()期望的是單個(gè)字符串值,而不是字符串值的列表。要生成這個(gè)單個(gè)字符串值,將lines傳遞到join()方法中,從列表的字符串中獲取一個(gè)單個(gè)連接的字符串。讓您的程序看起來像下面這樣:

#! python3
# bulletPointAdder.py - Adds Wikipedia bullet points to the start
# of each line of text on the clipboard.
import pyperclip
text = pyperclip.paste()
# Separate lines and add stars.
lines = text.split('\n')
for i in range(len(lines)):    # loop through all indexes for "lines" list
    lines[i] = '* ' + lines[i] # add star to each string in "lines" list
text = '\n'.join(lines)
pyperclip.copy(text)

當(dāng)這個(gè)程序運(yùn)行時(shí),它將剪貼板上的文本替換為每行開頭都有星號(hào)的文本?,F(xiàn)在程序完成了,您可以嘗試用復(fù)制到剪貼板的文本運(yùn)行它。

即使您不需要自動(dòng)化這個(gè)特定的任務(wù),您也可能希望自動(dòng)化一些其他類型的文本操作,比如刪除行尾的尾隨空格或者將文本轉(zhuǎn)換為大寫或小寫。無論您需要什么,您都可以使用剪貼板進(jìn)行輸入和輸出。

一個(gè)簡(jiǎn)短的程序:PigLatin

PigLatin是一種改變英語單詞的愚蠢的虛構(gòu)語言。如果一個(gè)單詞以元音開頭,單詞yay會(huì)加到它的末尾。如果一個(gè)單詞以一個(gè)輔音或輔音群開頭(比如chgr,那么這個(gè)輔音或輔音群會(huì)被移到單詞的末尾,后面跟著ay。

讓我們編寫一個(gè) Pig Latin 程序,它將輸出如下內(nèi)容:

Enter the English message to translate into Pig Latin:
My name is AL SWEIGART and I am 4,000 years old.
Ymay amenay isyay ALYAY EIGARTSWAY andyay Iyay amyay 4,000 yearsyay oldyay.

這個(gè)程序的工作原理是使用本章介紹的方法改變字符串。在文件編輯器中鍵入以下源代碼,并將文件保存為pigLat.py :

# English to Pig Latin
print('Enter the English message to translate into Pig Latin:')
message = input()
VOWELS = ('a', 'e', 'i', 'o', 'u', 'y')
pigLatin = [] # A list of the words in Pig Latin.
for word in message.split():
    # Separate the non-letters at the start of this word:
    prefixNonLetters = ''
    while len(word) > 0 and not word[0].isalpha():
        prefixNonLetters += word[0]
        word = word[1:]
    if len(word) == 0:
        pigLatin.append(prefixNonLetters)
        continue
    # Separate the non-letters at the end of this word:
    suffixNonLetters = ''
    while not word[-1].isalpha():
        suffixNonLetters += word[-1]
        word = word[:-1]
    # Remember if the word was in uppercase or title case.
    wasUpper = word.isupper()
    wasTitle = word.istitle()
    word = word.lower() # Make the word lowercase for translation.
    # Separate the consonants at the start of this word:
    prefixConsonants = ''
    while len(word) > 0 and not word[0] in VOWELS:
        prefixConsonants += word[0]
        word = word[1:]
    # Add the Pig Latin ending to the word:
    if prefixConsonants != '':
        word += prefixConsonants + 'ay'
    else:
        word += 'yay'
    # Set the word back to uppercase or title case:
    if wasUpper:
        word = word.upper()
    if wasTitle:
        word = word.title()
    # Add the non-letters back to the start or end of the word.
    pigLatin.append(prefixNonLetters + word + suffixNonLetters)
# Join all the words back together into a single string:
print(' '.join(pigLatin))

讓我們從頂部開始,逐行查看這段代碼:

# English to Pig Latin
print('Enter the English message to translate into Pig Latin:')
message = input()
VOWELS = ('a', 'e', 'i', 'o', 'u', 'y')

首先,我們要求用戶輸入要翻譯成PigLatin的英語文本。此外,我們創(chuàng)建一個(gè)常量,將每個(gè)小寫元音字母(和y )保存為一個(gè)字符串元組。這將在我們的程序中用到。

接下來,我們將創(chuàng)建pigLatin變量來存儲(chǔ)我們翻譯成 Pig Latin 的單詞:

pigLatin = [] # A list of the words in Pig Latin.
for word in message.split():
    # Separate the non-letters at the start of this word:
    prefixNonLetters = ''
    while len(word) > 0 and not word[0].isalpha():
        prefixNonLetters += word[0]
        word = word[1:]
    if len(word) == 0:
        pigLatin.append(prefixNonLetters)
        continue

我們需要每個(gè)單詞都是它自己的字符串,所以我們調(diào)用message.split()來獲得作為單獨(dú)字符串的單詞列表。字符串'My name is AL SWEIGART and I am 4,000 years old.'將導(dǎo)致split()返回['My', 'name', 'is', 'AL', 'SWEIGART', 'and', 'I', 'am', '4,000', 'years', 'old.']。

我們需要?jiǎng)h除每個(gè)單詞開頭和結(jié)尾的任何非字母,這樣像'old.'這樣的字符串就可以翻譯成'oldyay.'而不是'old.yay'。我們將這些非字母保存到一個(gè)名為prefixNonLetters的變量中。

    # Separate the non-letters at the end of this word:
    suffixNonLetters = ''
    while not word[-1].isalpha():
        suffixNonLetters += word[-1]
        word = word[:-1]

對(duì)單詞中的第一個(gè)字符調(diào)用isalpha()的循環(huán)將決定我們是否應(yīng)該從單詞中刪除一個(gè)字符,并將其連接到prefixNonLetters的末尾。如果整個(gè)單詞是由非字母字符組成的,比如'4,000',我們可以簡(jiǎn)單地將它添加到pigLatin列表中,然后繼續(xù)翻譯下一個(gè)單詞。我們還需要保存word字符串末尾的非字母。這段代碼類似于前面的循環(huán)。

接下來,我們將確保程序記住單詞是大寫還是大寫,這樣我們就可以在將單詞翻譯成 Pig Latin 后恢復(fù)它:

    # Remember if the word was in uppercase or title case.
    wasUpper = word.isupper()
    wasTitle = word.istitle()
    word = word.lower() # Make the word lowercase for translation.

對(duì)于for循環(huán)中的其余代碼,我們將使用小寫版本的word。

要將像sweigart這樣的單詞轉(zhuǎn)換成eigart-sway,我們需要?jiǎng)h除word開頭的所有輔音:

    # Separate the consonants at the start of this word:
    prefixConsonants = ''
    while len(word) > 0 and not word[0] in VOWELS:
        prefixConsonants += word[0]
        word = word[1:]

我們使用了一個(gè)類似于從word的開頭刪除非字母的循環(huán),除了現(xiàn)在我們正在刪除輔音并將它們存儲(chǔ)到一個(gè)名為prefixConsonants的變量中。

如果在單詞的開頭有任何輔音,它們現(xiàn)在在prefixConsonants中,我們應(yīng)該將那個(gè)變量和字符串'ay'連接到word的結(jié)尾。否則,我們可以假設(shè)word以元音開始,我們只需要連接'yay':

    # Add the Pig Latin ending to the word:
    if prefixConsonants != '':
        word += prefixConsonants + 'ay'
    else:
        word += 'yay'

回想一下,我們用word = word.lower()word設(shè)置為小寫版本。如果word最初是大寫或標(biāo)題大寫,這段代碼將把word轉(zhuǎn)換回它原來的大小寫:

    # Set the word back to uppercase or title case:
    if wasUpper:
        word = word.upper()
    if wasTitle:
        word = word.title()

for循環(huán)結(jié)束時(shí),我們將這個(gè)單詞,連同它原來的任何非字母前綴或后綴,添加到pigLatin列表中:

    # Add the non-letters back to the start or end of the word.
    pigLatin.append(prefixNonLetters + word + suffixNonLetters)
# Join all the words back together into a single string:
print(' '.join(pigLatin))

這個(gè)循環(huán)結(jié)束后,我們通過調(diào)用join()方法將字符串列表合并成一個(gè)字符串。這個(gè)字符串被傳遞給print()以在屏幕上顯示我們的豬拉丁。

你可以在找到其他簡(jiǎn)短的基于文本的 Python 程序,比如這個(gè)。

總結(jié)

文本是一種常見的數(shù)據(jù)形式,Python 附帶了許多有用的字符串方法來處理存儲(chǔ)在字符串值中的文本。您將在您編寫的幾乎每個(gè) Python 程序中使用索引、切片和字符串方法。

你現(xiàn)在寫的程序看起來不太復(fù)雜——它們沒有帶有圖像和彩色文本的圖形用戶界面。到目前為止,您使用print()顯示文本,并讓用戶使用input()輸入文本。然而,用戶可以通過剪貼板快速輸入大量文本。這種能力為編寫處理大量文本的程序提供了一個(gè)有用的途徑。這些基于文本的程序可能沒有華麗的窗口或圖形,但它們可以快速完成大量有用的工作。

另一種處理大量文本的方法是直接從硬盤上讀寫文件。你將在第 9 章中學(xué)習(xí)如何用 Python 做這件事。

這幾乎涵蓋了 Python 編程的所有基本概念!在本書的其余部分,您將繼續(xù)學(xué)習(xí)新概念,但是您現(xiàn)在已經(jīng)知道了足夠多的知識(shí),可以開始編寫一些有用的程序來自動(dòng)化任務(wù)。如果你想看一組簡(jiǎn)短的 Python 程序,這些程序是根據(jù)你到目前為止所學(xué)的基本概念構(gòu)建的,請(qǐng)查看asweigart/pythonstdiogames。嘗試手動(dòng)復(fù)制每個(gè)程序的源代碼,然后進(jìn)行修改,看看它們?nèi)绾斡绊懗绦虻男袨?。一旦你理解了程序是如何工作的,試著從頭開始重新創(chuàng)建程序。你不需要完全重新創(chuàng)建源代碼;只需關(guān)注程序做什么,而不是如何做。

您可能認(rèn)為自己沒有足夠的 Python 知識(shí)來做諸如下載網(wǎng)頁、更新電子表格或發(fā)送文本消息之類的事情,但這正是 Python 模塊的用武之地!這些由其他程序員編寫的模塊提供了一些函數(shù),使您可以輕松完成所有這些事情。因此,讓我們學(xué)習(xí)如何編寫真正的程序來完成有用的自動(dòng)化任務(wù)。

練習(xí)題

  1. 什么是轉(zhuǎn)義字符?

  2. \n\t轉(zhuǎn)義字符分別代表什么?

  3. 如何在字符串中放一個(gè)\反斜杠字符?

  4. 字符串值"Howl's Moving Castle"是有效的字符串。為什么單詞Howl's中的單引號(hào)字符不轉(zhuǎn)義就不是問題了?

  5. 如果你不想把\n放在你的字符串里,你怎么能寫一個(gè)有換行符的字符串呢?

  6. 下面的表達(dá)式表示什么?

    • 'Hello, world!'[1]
    • 'Hello, world!'[0:5]
    • 'Hello, world!'[:5]
    • 'Hello, world!'[3:]
  7. 下面的表達(dá)式表示什么?

    • 'Hello'.upper()
    • 'Hello'.upper().isupper()
    • 'Hello'.upper().lower()
  8. 下面的表達(dá)式表示什么?

    • 'Remember, remember, the fifth of November.'.split()
    • '-'.join('There can be only one.'.split())
  9. 有哪些字符串方法可以用來右對(duì)齊、左對(duì)齊和居中字符串?

  10. 如何從字符串的開頭或結(jié)尾修剪空白字符?

實(shí)踐項(xiàng)目

為了練習(xí),編寫執(zhí)行以下操作的程序。

表格打印

編寫一個(gè)名為printTable()的函數(shù),它獲取一個(gè)字符串列表列表,并將其顯示在一個(gè)組織良好的表格中,每列右對(duì)齊。假設(shè)所有內(nèi)部列表將包含相同數(shù)量的字符串。例如,該值可能如下所示:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

您的printTable()函數(shù)將打印以下內(nèi)容:

   apples Alice  dogs
  oranges   Bob  cats
 cherries Carol moose
   banana David goose

提示:您的代碼首先必須在每個(gè)內(nèi)部列表中找到最長(zhǎng)的字符串,以便整列足夠?qū)捯匀菁{所有的字符串。您可以將每列的最大寬度存儲(chǔ)為一個(gè)整數(shù)列表。printTable()函數(shù)可以從colWidths = [0] * len(tableData)開始,這將創(chuàng)建一個(gè)包含與tableData中內(nèi)部列表數(shù)量相同的0值的列表。這樣,colWidths[0]可以在tableData[0]中存儲(chǔ)最長(zhǎng)字符串的寬度,colWidths[1]可以在tableData[1]中存儲(chǔ)最長(zhǎng)字符串的寬度,以此類推。然后,您可以在colWidths列表中找到最大值,以找出要傳遞給rjust()字符串方法的整數(shù)寬度。

僵尸骰子

編程游戲是一種游戲類型,玩家不是直接玩游戲,而是編寫機(jī)器人程序來自主玩游戲。我已經(jīng)創(chuàng)建了一個(gè)僵尸骰子模擬器,它允許程序員在制作玩游戲的人工智能時(shí)練習(xí)他們的技能。僵尸骰子機(jī)器人可以很簡(jiǎn)單,也可以非常復(fù)雜,非常適合課堂練習(xí)或個(gè)人編程挑戰(zhàn)。

僵尸骰子是一個(gè)快速,有趣的史蒂夫杰克遜游戲骰子游戲。玩家是僵尸,試圖在不被擊中三次的情況下吃掉盡可能多的人腦。有一個(gè) 13 個(gè)骰子的杯子,上面有大腦、腳步聲和獵槍圖標(biāo)。骰子圖標(biāo)是有顏色的,每種顏色表示每個(gè)事件發(fā)生的可能性不同。每個(gè)骰子都有兩面有足跡,但綠色圖標(biāo)的骰子有更多面有大腦,紅色圖標(biāo)的骰子有更多散彈槍,黃色圖標(biāo)的骰子有平均分配的大腦和散彈槍。在每個(gè)玩家的回合中執(zhí)行以下操作:

  1. 將所有 13 個(gè)骰子放入杯中。玩家從杯中隨機(jī)抽取三個(gè)骰子,然后擲出。玩家總是擲出正好三個(gè)骰子。
  2. 他們把任何大腦(大腦被吃掉的人類)和獵槍(反擊的人類)放在一邊,清點(diǎn)起來。累積三支獵槍自動(dòng)以零分結(jié)束玩家的回合(不管他們有多少大腦)。如果他們有零到兩支獵槍,他們可以繼續(xù)滾動(dòng),如果他們想要的。他們也可以選擇結(jié)束他們的回合,每個(gè)大腦收集一點(diǎn)。
  3. 如果玩家決定繼續(xù)擲骰子,他們必須用腳步重?cái)S所有骰子。記住玩家必須總是擲出三個(gè)骰子;如果他們滾動(dòng)的腳步少于三步,他們必須從杯子里抽出更多的骰子。一個(gè)玩家可能會(huì)繼續(xù)擲骰子,直到他們得到三把散彈槍——失去一切——或者所有 13 個(gè)骰子都被擲出。玩家不能只重?cái)S一個(gè)或兩個(gè)骰子,也不能中途停止重?cái)S。
  4. 當(dāng)有人達(dá)到 13 個(gè)大腦時(shí),其余的玩家完成這一輪。最聰明的人贏了。如果出現(xiàn)平局,平局的玩家進(jìn)行最后一輪決勝局。

僵尸骰子有一個(gè)碰運(yùn)氣的游戲機(jī)制:你重新擲骰子越多,你能得到的大腦就越多,但你最終積累三把獵槍并輸?shù)粢磺械目赡苄跃驮酱?。一旦一名玩家達(dá)到 13 分,其余的玩家再獲得一次機(jī)會(huì)(可能會(huì)趕上),游戲結(jié)束。得分最高的玩家獲勝。你可以在asweigart/zombiedice找到完整的規(guī)則。

按照附錄 A 中的說明安裝帶 PIP 的zombiedice模塊。通過在交互式 Shell 中運(yùn)行以下內(nèi)容,您可以使用一些預(yù)制的機(jī)器人來運(yùn)行模擬器的演示:

>>> import zombiedice
>>> zombiedice.demo()
Zombie Dice Visualization is running. Open your browser to http://
localhost:51810 to view it.
Press Ctrl-C to quit.

該程序啟動(dòng)你的網(wǎng)絡(luò)瀏覽器,看起來像圖 6-1 。

Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:六、字符串操作

圖 6-1:僵尸骰子模擬器的網(wǎng)絡(luò)圖形用戶界面

您將通過編寫一個(gè)帶有turn()方法的類來創(chuàng)建機(jī)器人,當(dāng)輪到您的機(jī)器人擲骰子時(shí),模擬器將調(diào)用該方法。類已經(jīng)超出了本書的范圍,所以類代碼已經(jīng)在myzombie.py程序中為你設(shè)置好了,它在本書的可下載 ZIP 文件中nostarch.com/automatestuff2。寫方法本質(zhì)上和寫函數(shù)是一樣的,可以使用myZombie.py程序中的turn()代碼作為模板。在這個(gè)turn()方法中,只要你想讓你的機(jī)器人擲骰子,你就可以調(diào)用zombiedice.roll()函數(shù)。

import zombiedice
class MyZombie:
    def __init__(self, name):
        # All zombies must have a name:
        self.name = name
    def turn(self, gameState):
        # gameState is a dict with info about the current state of the game.
        # You can choose to ignore it in your code.
        diceRollResults = zombiedice.roll() # first roll
        # roll() returns a dictionary with keys 'brains', 'shotgun', and
        # 'footsteps' with how many rolls of each type there were.
        # The 'rolls' key is a list of (color, icon) tuples with the
        # exact roll result information.
        # Example of a roll() return value:
        # {'brains': 1, 'footsteps': 1, 'shotgun': 1,
        #  'rolls': [('yellow', 'brains'), ('red', 'footsteps'),
        #            ('green', 'shotgun')]}
        # REPLACE THIS ZOMBIE CODE WITH YOUR OWN:
        brains = 0
        while diceRollResults is not None:
            brains += diceRollResults['brains']
            if brains < 2:
                diceRollResults = zombiedice.roll() # roll again
            else:
                break
zombies = (
    zombiedice.examples.RandomCoinFlipZombie(name='Random'),
    zombiedice.examples.RollsUntilInTheLeadZombie(name='Until Leading'),
    zombiedice.examples.MinNumShotgunsThenStopsZombie(name='Stop at 2
Shotguns', minShotguns=2),
    zombiedice.examples.MinNumShotgunsThenStopsZombie(name='Stop at 1
Shotgun', minShotguns=1),
    MyZombie(name='My Zombie Bot'),
    # Add any other zombie players here.
)
# Uncomment one of the following lines to run in CLI or Web GUI mode:
#zombiedice.runTournament(zombies=zombies, numGames=1000)
zombiedice.runWebGui(zombies=zombies, numGames=1000)

turn()方法有兩個(gè)參數(shù):selfgameState。在最初的幾個(gè)僵尸機(jī)器人中,你可以忽略這些,如果你想了解更多,可以稍后查閱在線文檔了解詳細(xì)信息。對(duì)于初始擲骰子,turn()方法應(yīng)該至少調(diào)用zombiedice.roll()一次。然后,根據(jù)機(jī)器人使用的策略,它可以再次調(diào)用zombiedice.roll()任意多次。在myZombie.py中,turn()方法調(diào)用zombiedice.roll()兩次,這意味著僵尸機(jī)器人將總是每回合擲骰子兩次,而不管擲骰子的結(jié)果如何。

zombiedice.roll()的返回值告訴你的代碼擲骰子的結(jié)果。這是一本有四個(gè)鍵的字典。其中三個(gè)鍵,'shotgun'、'brains''footsteps',有整數(shù)值,表示有多少骰子出現(xiàn)了這些圖標(biāo)。第四個(gè)'rolls'鍵的值是每個(gè)骰子點(diǎn)數(shù)的元組列表。元組包含兩個(gè)字符串:索引0處骰子的顏色和索引1處滾動(dòng)的圖標(biāo)。請(qǐng)看turn()方法定義中的代碼注釋作為例子。如果機(jī)器人已經(jīng)滾了三把獵槍,那么zombiedice.roll()就會(huì)返回None。

試著寫一些你自己的機(jī)器人來玩僵尸骰子,看看它們與其他機(jī)器人相比如何。具體來說,嘗試創(chuàng)建以下機(jī)器人:

  • 一個(gè)機(jī)器人,在第一次投擲后,隨機(jī)決定是繼續(xù)還是停止
  • 一個(gè)機(jī)器人在滾過兩個(gè)大腦后停止?jié)L動(dòng)
  • 一個(gè)機(jī)器人滾了兩把獵槍后就停止了滾動(dòng)
  • 最初決定擲骰子一到四次的機(jī)器人,但如果擲出兩把獵槍,就會(huì)提前停止
  • 一個(gè)機(jī)器人在滾過比大腦還多的獵槍后停止?jié)L動(dòng)

通過模擬器運(yùn)行這些機(jī)器人,看看它們之間的比較如何。你也可以在檢查一些預(yù)制的機(jī)器人的代碼。如果你發(fā)現(xiàn)自己在現(xiàn)實(shí)世界中玩這個(gè)游戲,你會(huì)受益于數(shù)以千計(jì)的模擬游戲,告訴你最好的策略之一是一旦你滾了兩把獵槍就停下來。但是你可以試試碰運(yùn)氣…文章來源地址http://www.zghlxwxcb.cn/news/detail-403051.html

到了這里,關(guān)于Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:六、字符串操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:十六、使用 CSV 文件和 JSON 數(shù)據(jù)

    Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:十六、使用 CSV 文件和 JSON 數(shù)據(jù)

    原文:https://automatetheboringstuff.com/2e/chapter16/ 在第 15 章,你學(xué)習(xí)了如何從 PDF 和 Word 文檔中提取文本。這些文件是二進(jìn)制格式的,需要特殊的 Python 模塊來訪問它們的數(shù)據(jù)。另一方面,CSV 和 JSON 文件只是純文本文件。您可以在文本編輯器(如 Mu)中查看它們。但是 Python 還附帶

    2023年04月08日
    瀏覽(657)
  • Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:二十、使用 GUI 自動(dòng)化控制鍵盤和鼠標(biāo)

    Python 自動(dòng)化指南(繁瑣工作自動(dòng)化)第二版:二十、使用 GUI 自動(dòng)化控制鍵盤和鼠標(biāo)

    原文:https://automatetheboringstuff.com/2e/chapter20/ 了解用于編輯電子表格、下載文件和啟動(dòng)程序的各種 Python 模塊是很有用的,但有時(shí)您需要使用的應(yīng)用沒有任何模塊。在計(jì)算機(jī)上實(shí)現(xiàn)任務(wù)自動(dòng)化的終極工具是你編寫的直接控制鍵盤和鼠標(biāo)的程序。這些程序可以通過發(fā)送虛擬擊鍵和

    2024年02月09日
    瀏覽(101)
  • 讓自動(dòng)化測(cè)試秒殺繁瑣操作?試試PO模式設(shè)計(jì)框架

    讓自動(dòng)化測(cè)試秒殺繁瑣操作?試試PO模式設(shè)計(jì)框架

    目錄:導(dǎo)讀 引言 po模式 優(yōu)勢(shì): ?目錄解釋: 頁面對(duì)象設(shè)計(jì)模式: base基礎(chǔ)層: page對(duì)象層: ?test:測(cè)試層 data數(shù)據(jù)層: ?common層: ?untils: ?config層: run層: report: 結(jié)語 你是否曾經(jīng)因?yàn)槊看胃鹿δ芏家匦聦懸欢炎詣?dòng)化測(cè)試代碼而感到疲憊不堪? 或者因?yàn)轫撁嬖氐念l繁變

    2024年02月02日
    瀏覽(101)
  • 無需繁瑣手工操作,如何利用Web自動(dòng)化測(cè)試元素定位做到快速高效的測(cè)試?

    在Web自動(dòng)化測(cè)試中,元素定位是非常重要的環(huán)節(jié)。因?yàn)槲覀冃枰业叫枰M(jìn)行操作的頁面元素,例如按鈕、輸入框、下拉菜單等等。元素定位可以幫助我們?cè)谧詣?dòng)化測(cè)試中對(duì)這些元素進(jìn)行操作,如點(diǎn)擊、輸入和驗(yàn)證等。 在華為工作了10年的大佬出的Web自動(dòng)化測(cè)試教程,華為現(xiàn)

    2024年02月05日
    瀏覽(448)
  • 告別重復(fù)工作,用Python實(shí)現(xiàn)辦公自動(dòng)化,提高工作效率

    告別重復(fù)工作,用Python實(shí)現(xiàn)辦公自動(dòng)化,提高工作效率

    996 一直是互聯(lián)網(wǎng)老生常談的話題了,但拋開其他只談工作本身,你有沒有想過, 下班晚、加班,有時(shí)候可能是因?yàn)樽约汗ぷ鞅容^低效? 先給你分享一個(gè)案例: 場(chǎng)景是在維護(hù)日活超過 3 億用戶的微博私信平臺(tái),在一個(gè)業(yè)務(wù)模塊中,需要批量替換 200 臺(tái)服務(wù)器中的軟件配置,而

    2024年02月06日
    瀏覽(94)
  • 深度解析appium自動(dòng)化測(cè)試,掌握移動(dòng)端測(cè)試的最新技術(shù),從此告別繁瑣手工測(cè)試

    目錄 一、什么是appium? 二、appium的使用場(chǎng)景 三、appium的基礎(chǔ)知識(shí) 四、appium代碼示例

    2024年01月19日
    瀏覽(92)
  • Python自動(dòng)化Clicknium指南1

    Python自動(dòng)化Clicknium指南1

    Clicknium 是一個(gè)Python UI自動(dòng)化庫,主要用來自動(dòng)化Windows桌面應(yīng)用和網(wǎng)頁應(yīng)用。由于Clicknium沒中文文檔, 本文將系統(tǒng)的介紹一下Clicknium的使用方法。 Clicknium通過錄制鼠標(biāo)點(diǎn)擊UI元素,自動(dòng)生成Locator,其中存儲(chǔ)了該UI元素的各種屬性,使Clicknium可以通過locator重新定位到對(duì)應(yīng)的UI元

    2024年02月06日
    瀏覽(85)
  • 《編程菜鳥學(xué) Python 數(shù)據(jù)分析》讓工作自動(dòng)化起來!

    《編程菜鳥學(xué) Python 數(shù)據(jù)分析》讓工作自動(dòng)化起來!

    隨著我國(guó)企業(yè)數(shù)字化和信息化的深入,企業(yè)對(duì)辦公自動(dòng)化的效率和靈活性要求越來越高。Python作為一種開源的軟件應(yīng)用開發(fā)方式,通過提供強(qiáng)大豐富的庫文件包,極大地簡(jiǎn)化了應(yīng)用開發(fā)過程,降低了技術(shù)門檻。Python開發(fā)有哪些優(yōu)勢(shì)、挑戰(zhàn)以及實(shí)踐方法呢? 在我們的日常工作中

    2024年04月09日
    瀏覽(99)
  • 10個(gè)Python自動(dòng)化腳本助你工作更加高效

    所以,請(qǐng)你把這篇文章放在你的收藏清單上,以備不時(shí)之需,在IT行業(yè)里,程序員的學(xué)習(xí)永無止境…… 現(xiàn)在,讓我們開始吧。 ? 使用這個(gè)很棒的自動(dòng)化腳本,可以幫助把圖像處理的更好,你可以像在 Photoshop 中一樣編輯它們。 該腳本使用流行的是 Pillow 模塊 通過使用以下自動(dòng)

    2024年02月06日
    瀏覽(95)
  • 【Python數(shù)據(jù)分析】讓工作自動(dòng)化起來,無所不能的Python

    【Python數(shù)據(jù)分析】讓工作自動(dòng)化起來,無所不能的Python

    隨著我國(guó)企業(yè)數(shù)字化和信息化的深入,企業(yè)對(duì)辦公自動(dòng)化的效率和靈活性要求越來越高。Python作為一種開源的軟件應(yīng)用開發(fā)方式,通過提供強(qiáng)大豐富的庫文件包,極大地簡(jiǎn)化了應(yīng)用開發(fā)過程,降低了技術(shù)門檻。Python開發(fā)有哪些優(yōu)勢(shì)、挑戰(zhàn)以及實(shí)踐方法呢? 在我們的日常工作中

    2024年04月13日
    瀏覽(117)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包