重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
編寫循環的技巧,for循環包含了常見的計數器式循環。由于通常for循環比while循環更容易寫,也執行得更快,所以for循環一般是你遍歷序列或其他可迭代對象時的首選。事實上,作為一條通用法則,你應該克制在Python中使用計數方式的誘惑——Python提供的迭代工具,能幫你把像C這樣低級語言中循環集合體的工作自動化。不過,有些情況下你還是需要以更為特定的方式進行迭代。例如,如果你需要在列表中每隔一個元素或每隔兩個元素進行訪問,或是要同時修改列表呢?如果在同一個for循環內,并行遍歷一個以上的序列呢?如果你也需要進行索引呢?
十年的蕪湖縣網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網整合營銷推廣的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整蕪湖縣建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯從事“蕪湖縣網站設計”,“蕪湖縣網站推廣”以來,每個客戶項目都認真落實執行。
你總是可以用while循環和手動索引運算來編寫這些獨特的循環,但是python提供了一套內置函數,可以幫你在for循環內定制迭代:·內置函數range (Python 0.X及之后版本可用)返回一系列連續增加的整數,可作為for中的索引。內置函數zip (Python 2.0及之后版本可用)返回一系列并行元素的元組,可用于在for中內遍歷多個序列。內置函數enumerate (Python 2.3及之后版本可用)同時生成可迭代對象中元素的值和索引,因而我們不必再手動計數。內置函數map (Python 1.0及之后版本可用)在Python 2.X中與zip有著相似的效果,但是在3.X中 map 的這一角色被移除了。因為for循環可能會比基于while的計數器循環運行得更快,所以借助這些工具并盡可能地使用for循環,會讓你受益匪淺。讓我們在常見的使用場景下,依次看一看這些內置函數吧。我們將會看到,它們的用法在Python 2.X和3.X中稍有不同,同時它們中的一些要比其他的更加有效。
for ... in ...
//?for?...?in?字符串
for?i?in?'abc':
print(i)
'''
a
b
c
'''
//?for?...?in?數組
for?i?in?['a',?'b',?'c']:
print(i)
'''
a
b
c
'''
//?for?...?in?元組
for?i?in?('a',?'b',?'c'):
print(i)
'''
a
b
c
'''
//?for?...?in?字典(得到的是字典的key)
for?k?in?{'學號':30,'姓名':'小明'}:
print(k)
'''
姓名
學號
'''
//?for?...?in?字典.items()(得到的是字典的key,?value)
for?k,?v?in?{'學號':30,'姓名':'小明'}.items():
print(k,?v)
'''
姓名?小明
學號?30
'''
for ... in range(...)
//?for?...?in?range(num)
for?i?in?range(3):
print(i)
'''
1
2
'''
//?for?...?in?range(num1,?num2)
for?i?in?range(1,?3):
print(i)
'''
1
2
'''
//?for?...?in?range(num1,?num2,?num3)
for?i?in?range(3,?1,?-1):
print(i)
'''
3
2
'''
for?i?in?range(1,?5,?2):
print(i)
'''????????
1
3
'''
倒敘
for?i?in?reversed([1,2,3,4]):
print(i)
’‘’
4
3
2
1
‘’‘
又想得到遍歷次數,又想得到數組值
for i,e in enumerate(array):
for?i,e?in?enumerate(['21dw',?55,?22,?'rw']):
print(i,?e)
'''
0?21dw
1?55
2?22
3?rw
'''
列表生成式
[...for ... in array]]
print([x?*?x?for?x?in?[2,?34,?324,?43]])
'''
[4,?1156,?104976,?1849]
'''
//相當于
list?=?[]
for?x?in?[2,?34,?324,?43]:
list.append(x?*?x)
print(list)
想要實現從 0 到 10 的累加,可以執行如下代碼:
print("計算 0+2+...+10 的結果為:")
#保存累加結果的變量result = 0
#逐個獲取從 0到 10 這些值,并做累加操作
for i in range(0,10):
result += iprint(result)
上面代碼中,使用了 range() 函數,此函數是 Python 內置函數,用于生成一系列連續整數,多用于 for 循環中。
擴展資料:
使用Python編程時的注意事項:
1、初始變化量
在Python里,一個表達式中的名字在它被賦值之前是沒法使用的。這是有意而為的:這樣能避免一些輸入失誤,同時也能避免默認究竟應該是什么類型的問題(0,None,””,[],?)。記住把計數器初始化為0,列表初始化為[],以此類推。
2、從第一列開始
確保把頂層的,未嵌套的代碼放在最左邊第一列開始。這包括在模塊文件中未嵌套的代碼,以及在交互提示符中未嵌套的代碼。Python使用縮進的辦法來區分嵌套的代碼段,因此在你代碼左邊的空格意味著嵌套的代碼塊。除了縮進以外,空格通常是被忽略掉的。
可以用假設法啊。這是計算機擅長的方法,用一個循環先假設循環節為1,然后依次假設2,3,4,5,6,7,8,9
不用再多了。再多也看不過來。這樣就可以輕松算出來了。
1234567891011import sysx=0.12312312313tmps = "%s"%xp = tmps.find('.')if p0: sys.exit()tmps = tmps[p+1:]for i in xrange(1,9): if tmps[:i]== tmps[i:i*2] and tmps[i:i*2]== tmps[i*2:i*3] : print 'result is %d'%i sys.exit()print 'not found'
上面是一個簡單的例子。
循環是一種常用的程序控制結構。我們常說,機器相比人類的最大優點之一,就是機器可以不眠不休的重復做某件事情,但人卻不行。而“循環”,則是實現讓機器不斷重復工作的關鍵概念。
在循環語法方面,Python 表現的即傳統又不傳統。它雖然拋棄了常見的 for(init;condition;incrment) 三段式結構,但還是選擇了 for 和 while 這兩個經典的關鍵字來表達循環。絕大多數情況下,我們的循環需求都可以用 forin來滿足, while相比之下用的則更少些。
雖然循環的語法很簡單,但是要寫好它確并不容易。在這篇文章里,我們將探討什么是“地道”的循環代碼,以及如何編寫它們。
什么是“地道”的循環?
“地道”這個詞,通常被用來形容某人做某件事情時,非常符合當地傳統,做的非常好。打個比方,你去參加一個朋友聚會,同桌的有一位廣東人,對方一開口,句句都是標準京腔、完美兒化音。那你可以對她說:“您的北京話說的真地道”。
既然“地道”這個詞形容的經常是口音、做菜的口味這類實實在在的東西,那“地道”的循環代碼又是什么意思呢?讓我拿一個經典的例子來解釋一下。
如果你去問一位剛學習 Python 一個月的人:“如何在遍歷一個列表的同時獲取當前下標?”。他可能會交出這樣的代碼:
?
上面的循環雖然沒錯,但它確一點都不“地道”。一個擁有三年 Python 開發經驗的人會說,代碼應該這么寫:
enumerate() 是 Python 的一個內置函數,它接收一個“可迭代”對象作為參數,然后返回一個不斷生成 (當前下標,當前元素) 的新可迭代對象。這個場景使用它最適合不過。
所以,在上面的例子里,我們會認為第二段循環代碼比第一段更“地道”。因為它用更直觀的代碼,更聰明的完成了工作。
enumerate() 所代表的編程思路
不過,判斷某段循環代碼是否地道,并不僅僅是以知道或不知道某個內置方法作為標準。我們可以從上面的例子挖掘出更深層的東西。
如你所見,Python 的 for 循環只有 forin這一種結構,而結構里的前半部分 - 賦值給 item- 沒有太多花樣可玩。所以后半部分的 可迭代對象 是我們唯一能夠大做文章的東西。而以 enumerate() 函數為代表的“修飾函數”,剛好提供了一種思路:通過修飾可迭代對象來優化循環本身。
這就引出了我的第一個建議。
建議1:使用函數修飾被迭代對象來優化循環
使用修飾函數處理可迭代對象,可以在各種方面影響循環代碼。而要找到合適的例子來演示這個方法,并不用去太遠,內置模塊 itertools 就是一個絕佳的例子。
簡單來說,itertools 是一個包含很多面向可迭代對象的工具函數集。我在之前的系列文章《容器的門道》里提到過它。
如果要學習 itertools,那么 Python 官方文檔 是你的首選,里面有非常詳細的模塊相關資料。但在這篇文章里,側重點將和官方文檔稍有不同。我會通過一些常見的代碼場景,來詳細解釋它是如何改善循環代碼的。
1. 使用 product 扁平化多層嵌套循環
雖然我們都知道“扁平的代碼比嵌套的好”。但有時針對某類需求,似乎一定得寫多層嵌套循環才行。比如下面這段:
?
對于這種需要嵌套遍歷多個對象的多層循環代碼,我們可以使用 product() 函數來優化它。product() 可以接收多個可迭代對象,然后根據它們的笛卡爾積不斷生成結果。
?
相比之前的代碼,使用 product() 的函數只用了一層 for 循環就完成了任務,代碼變得更精煉了。
2. 使用 islice 實現循環內隔行處理
有一份包含 Reddit 帖子標題的外部數據文件,里面的內容格式是這樣的:
?
可能是為了美觀,在這份文件里的每兩個標題之間,都有一個 "---" 分隔符。現在,我們需要獲取文件里所有的標題列表,所以在遍歷文件內容的過程中,必須跳過這些無意義的分隔符。
參考之前對 enumerate() 函數的了解,我們可以通過在循環內加一段基于當前循環序號的 if 判斷來做到這一點:
?
但對于這類在循環內進行隔行處理的需求來說,如果使用 itertools 里的 islice() 函數修飾被循環對象,可以讓循環體代碼變得更簡單直接。
islice(seq,start,end,step) 函數和數組切片操作( list[start:stop:step] )有著幾乎一模一樣的參數。如果需要在循環內部進行隔行處理的話,只要設置第三個遞進步長參數 step 值為 2 即可(默認為 1)。
?
3. 使用 takewhile 替代 break 語句
有時,我們需要在每次循環開始時,判斷循環是否需要提前結束。比如下面這樣:
?
對于這類需要提前中斷的循環,我們可以使用 takewhile() 函數來簡化它。takewhile(predicate,iterable)會在迭代 iterable 的過程中不斷使用當前對象作為參數調用 predicate 函數并測試返回結果,如果函數返回值為真,則生成當前對象,循環繼續。否則立即中斷當前循環。
使用 takewhile 的代碼樣例:
?
itertools 里面還有一些其他有意思的工具函數,他們都可以用來和循環搭配使用,比如使用 chain 函數扁平化雙層嵌套循環、使用 zip_longest 函數一次同時循環多個對象等等。
篇幅有限,我在這里不再一一介紹。如果有興趣,可以自行去官方文檔詳細了解。
4. 使用生成器編寫自己的修飾函數
除了 itertools 提供的那些函數外,我們還可以非常方便的使用生成器來定義自己的循環修飾函數。
讓我們拿一個簡單的函數舉例:
?
在上面的函數里,循環體內為了過濾掉所有奇數,引入了一條額外的 if 判斷語句。如果要簡化循環體內容,我們可以定義一個生成器函數來專門進行偶數過濾:
?
將 numbers 變量使用 even_only 函數裝飾后, sum_even_only_v2 函數內部便不用繼續關注“偶數過濾”邏輯了,只需要簡單完成求和即可。
Hint:當然,上面的這個函數其實并不實用。在現實世界里,這種簡單需求最適合直接用生成器/列表表達式搞定:sum(numfornuminnumbersifnum%2==0)
建議2:按職責拆解循環體內復雜代碼塊
我一直覺得循環是一個比較神奇的東西,每當你寫下一個新的循環代碼塊,就好像開辟了一片黑魔法陣,陣內的所有內容都會開始無休止的重復執行。
但我同時發現,這片黑魔法陣除了能帶來好處,它還會引誘你不斷往陣內塞入越來越多的代碼,包括過濾掉無效元素、預處理數據、打印日志等等。甚至一些原本不屬于同一抽象的內容,也會被塞入到同一片黑魔法陣內。
#腳本里面直接這樣寫就好了import randomdef R(): print (random.randint(1,1000))for i in range(1,10): R()