所以這里將創(chuàng)建3個文件夾,分別用于存放這三種音樂文件。 新建一個名為download_qqMusic_by_songname.py的模塊文件,在其中添加如下代碼▼: 1import os 2 3# 創(chuàng)建歌曲下載目錄,3個品質(zhì)音樂文件分開存放 4DOWNLOAD_DIRS = ['D:/qqMusic/單曲/' + x for x in ['HQ', 'SQ', 'VQ']] 5for download_dir in DOWNLOAD_DIRS: 6 if not os.path.exists(download_dir): 7 os.makedirs(download_dir) 代碼注解>> Line1:導(dǎo)入內(nèi)置os模塊。 Line4:變量DOWNLOAD_DIRS存儲3個目錄路徑名,因其在后面多處(包括函數(shù)內(nèi)部)會用到,所以應(yīng)聲明為“公共變量”,而Python中一般使用全大寫字母來命名公共變量。 后面是一個列表推導(dǎo)式,關(guān)于它的具體用法一會再提。 這里變量DOWNLOAD_DIRS得到的值是: 1['D:/qqMusic/單曲/HQ', 'D:/qqMusic/單曲/SQ', 'D:/qqMusic/單曲/VQ'] Line5~7:使用一個for循環(huán)語句來自動創(chuàng)建文件夾。
如果執(zhí)行上面的代碼,便會在D:盤目錄下自動生成3個文件夾(如下圖▼): ▲<上圖>QQ音樂_代碼編寫_創(chuàng)建下載目錄 下面再看看什么是 列表推導(dǎo)式 ? 6.2 列表推導(dǎo)式 列表推導(dǎo)式亦稱“列表解析”,是一種能按照一定規(guī)則從序列中生成新列表的方法。 而這個「規(guī)則」可以是運算、調(diào)用方法或嵌套函數(shù)等等復(fù)雜表達(dá)式,還可使用if語句對結(jié)果進(jìn)行過濾。 它是Python語法中既簡單又方便,且非常有特色的用法,因為它最終只有一行表達(dá)式,無論其內(nèi)部復(fù)雜程度如何。 同時,你也可簡單理解它為for循環(huán)語句的衍生用法。 基本用法: 1# range(5)是由0~4整數(shù)組成的list,對其每個元素計算2次冪后生成一個新的list 2>>> [x**2 for x in range(5)] 3[0, 1, 4, 9, 16] 4 5# 對其每個元素乘以2并加1后生成一個新的list 6>>> [x*2+1 for x in range(5)] 7[1, 3, 5, 7, 9] 這里的x是約定俗成的變量名,當(dāng)然你也可換成其他字符。 改變元素數(shù)據(jù)類型: 1# range(5)中元素為數(shù)字,生成新list中元素類型變?yōu)樽址?br>2>>> ['a'+str(x) for x in range(5)] 對元素調(diào)用方法: 1# 刪除原list中元素頭尾的空格 2>>> food = [' 米飯 ', ' 面條', ' 面 包 ', '漢堡 '] 3>>> [x.strip() for x in food] 4['米飯', '面條', '面 包', '漢堡'] strip()是字符串方法,用于移除字符串頭尾的空格或換行符,但中間的不刪除。 用if子句過濾: 1# 從0~9中篩選偶數(shù),組成新列表 上面的if子句均用在for語句之后,用于過濾篩選滿足條件的元素,新列表元素個數(shù)可能減少。 而將if...else形式子句放在for語句之前,還能實現(xiàn)根據(jù)條件對元素重新賦值,而新列表元素個數(shù)不變。如: 1# 能被3整除的元素取原值,否則取相反數(shù) 2>>> [x if x%3 == 0 else -x for x in range(10)] 3[0, -1, -2, 3, -4, -5, 6, -7, -8, 9] 多個for子句: 列表解析中可包含多個for子句,相當(dāng)于多層普通的for循環(huán)語句塊,循環(huán)順序從前至后。例: 1>>> lst1 = [2, -5, 8] 再比如三個for子句: 1>>> lst1 = ['X1', 'X2']; lst2 = ['Y1', 'Y2']; lst3 = ['Z1', 'Z2'] 2>>> [x + y + z for x in lst1 for y in lst2 for z in lst3] 3['X1Y1Z1', 'X1Y1Z2', 'X1Y2Z1', 'X1Y2Z2', 'X2Y1Z1', 'X2Y1Z2', 'X2Y2Z1', 'X2Y2Z2'] 當(dāng)然,上面的也等價于這樣寫: 1>>> lst = [] 很顯然,使用列表推導(dǎo)式的寫法更簡潔、易閱讀,一行代碼全部搞定! 嵌套列表解析: 這個很容易與上面的“多個for子句”搞混淆,實際上嵌套列表解析相當(dāng)于在一個列表推導(dǎo)式的前部分結(jié)果位置處又嵌入一個列表推導(dǎo)式。 仍以上前一個例子進(jìn)行對比說明: 1>>> lst1 = [2, -5, 8]; lst2 = [-1, 4, 0.6] 2>>> [[x + y for x in lst1] for y in lst2] # 嵌套列表解析 3[[1, -6, 7], [6, -1, 12], [2.6, -4.4, 8.6]] # 結(jié)果1 4# 上前一個例子的結(jié)果如下 5>>> [x + y for x in lst1 for y in lst2] # 多個for子句的列表解析 6[1, 6, 2.6, -6, -1, -4.4, 7, 12, 8.6] # 結(jié)果2 可以看出,“結(jié)果1”是一個嵌套列表,有3個元素(每個元素又是一個包含3個元素的列表);而“結(jié)果2”是一個普通列表,有9個元素。 且在循環(huán)運算順序上,“結(jié)果1”是從后往前,即先外層后內(nèi)層;而“結(jié)果2”是從前往后。 利用“嵌套列表解析”的特性,我們一行代碼即可輕松對一個矩陣進(jìn)行轉(zhuǎn)置。如: 1# 使用“嵌套列表解析”將3X4的矩陣列表轉(zhuǎn)置成4X3的矩陣列表 否則,可能需下面繁瑣的多行代碼才能實現(xiàn): 1# 使用“普通for語句”將3X4的矩陣列表轉(zhuǎn)置成4X3的矩陣列表 2>>> matrix = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]] 3>>> transposed = [] 4>>> for i in range(4): 5... transposed_temp = [] 6... for x in matrix: 7... transposed_temp.append(x[i]) 8... transposed.append(transposed_temp) 9... 10>>> transposed 11[[11, 21, 31], [12, 22, 32], [13, 23, 33], [14, 24, 34]] 關(guān)于“列表推導(dǎo)式”,實際上還能組合、衍生出更高級的用法,只要你敢想。 比如還能有“字典推導(dǎo)式”: 1# 用字典方式寫出數(shù)字1~9各自的平方和 但作為編程者,首要目的應(yīng)是實現(xiàn)功能,其次是讓代碼簡單易懂,而并非要代碼多么炫酷。 所以,我們更應(yīng)結(jié)合自身需要選擇適合的方法來達(dá)到目的。 現(xiàn)在再回頭看6.1小節(jié)中Line4的代碼▼,是不是就明白了呢? 1DOWNLOAD_DIRS = ['D:/qqMusic/單曲/' + x for x in ['HQ', 'SQ', 'VQ']] 6.3 讀取歌單文件 這里的“歌單文件”即上一章中提到的《SongsList.txt》,是一個普通的文本文檔,用于存儲我們希望搜索并下載的歌曲名稱。 類似這樣▼: ▲<上圖>QQ音樂_代碼編寫_SongsList.txt 每一行都是自行添加的一首歌曲名稱/關(guān)鍵詞,現(xiàn)在我們要用Python從中讀取關(guān)鍵詞,并返回一個列表。 這里,定義一個名為get_keywords()的函數(shù)來實現(xiàn)以上功能。代碼如下▼: 1# 定義函數(shù),從SongsList.txt中讀取需下載歌曲關(guān)鍵詞 代碼注解>> Line5:變量fn用于存儲歌單文檔的文件名,./表示在當(dāng)前目錄下。(你也可更換) Line6 & Line9:對fn文件作個判斷,如果存在則讀取數(shù)據(jù);否則打印提示“不存在”,并退出程序。 Line8:變量keywords用于存放經(jīng)讀取并處理后的“關(guān)鍵詞”。后面的“列表推導(dǎo)式”實現(xiàn)提取關(guān)鍵詞并返回成列表的功能。 值得注意的是兩個strip()的使用,左邊的是對每行的“關(guān)鍵詞”刪除前后空格&換行;而右邊的是判斷每一行是否為空。 假如不加這兩個strip()會有什么影響呢?以上圖《SongsList.txt》為例: 1# 原代碼 2>>> keywords = [x.strip() for x in f if x.strip()] 3>>> keywords 4['你的酒館對我打了烊', '海闊天空', '銀河里最像的', '來自天堂的魔鬼', '等你下課'] 5 6# 刪除右邊的'strip()' 7>>> keywords = [x.strip() for x in f] 8>>> keywords 9['你的酒館對我打了烊', '', '海闊天空', '銀河里最像的', '來自天堂的魔鬼', '', '等你下課', '', ''] 10 11# 刪除左邊的'strip()' 12>>> keywords = [x for x in f if x.strip()] 13>>> keywords 14['你的酒館對我打了烊', '海闊天空', '銀河里最像的', '來自天堂的魔鬼', '等你下課'] 15 16# 同時刪除左/右兩個'strip()' 17>>> keywords = [x for x in f] 18>>> keywords 19['你的酒館對我打了烊', 20 '', 21 '海闊天空', 22 '銀河里最像的', 23 '來自天堂的魔鬼', 24 '', 25 '等你下課', 26 '', 27 ''] Line11:sys.exit()是退出應(yīng)用程序,需要import sys模塊,見Line2。 Line12:最后return keywords函數(shù)返回keywords,是一個由“關(guān)鍵詞”組成的列表。 6.4 回顧小結(jié) 本章主要完成了2個步驟,即“創(chuàng)建下載目錄”和“讀取歌單文件”的代碼編寫,并引出了”列表推導(dǎo)式“的概念。 所涉及內(nèi)容并不多,但“列表推導(dǎo)式”確實是Python非常好用的特性之一,大家可多理解、多試驗、多應(yīng)用。 6.5 重點筆記 6.5.1 列表推導(dǎo)式 關(guān)于「列表推導(dǎo)式」及「字典推導(dǎo)式」的概念請參見6.2小節(jié)。 6.5.2 strip()方法 strip()方法用于移除字符串頭尾指定的字符(默認(rèn)為空白符,包括空格符、換行符 、制表符 、回車符 )或字符序列,但中間的不刪除。 |
|