代替for迴圈的方法

2021-09-01 12:25:51 字數 3871 閱讀 6940

為什麼要挑戰自己在**裡不寫for loop?因為這樣可以迫使你去使用比較高階、地道的語法或庫。文中以python為例子,講了不少大家其實在別人的**裡都見過、但自己很少用的語法。

這是乙個挑戰。我要你避免在任何情況下寫for迴圈。同樣的,我也要你找到一種場景——除了用for迴圈以外,用其他方法寫都太難。請分享你的發現,我非常想聽到這些

距離我開始探索超棒的python語言特性已經有一段時間了。一開始,這只是我給自己的乙個挑戰,練習使用更多的語言特性來替代我從其他程式語言那裡所學到的。但是事情漸漸變得更有趣了!**不止變得更簡短整潔,而且看起來更加結構化和有規律,在這篇文章中我將更多地介紹這些好處。

首先,讓我們退一步看看在寫乙個for迴圈背後的直覺是什麼:

1.遍歷乙個序列提取出一些資訊

2.從當前的序列中生成另外的序列

3.寫for迴圈已經是我的第二天性了,因為我是乙個程式設計師

幸運的是,python裡面已經有很棒的工具幫你達到這些目標!你需要做的只是轉變思想,用不同的角度看問題。

1.更少的**行數

2.更好的**閱讀性

3.只將縮排用於管理**文字

let』s see the code skeleton below:

看看下面這段**的構架:

python

# 1with ...:

for ...:

if ...:

try:

except:

else:

這個例子使用了多層巢狀的**,這是非常難以閱讀的。我在這段**中發現它無差別使用縮排把管理邏輯(with, try-except)和業務邏輯(for, if)混在一起。如果你遵守只對管理邏輯使用縮排的規範,那麼核心業務邏輯應該立刻脫離出來。

「扁平結構比巢狀結構更好」 – 《python之禪》

1. 列表解析/生成器表示式

看乙個簡單的例子,這個例子主要是根據乙個已經存在的序列編譯乙個新序列:

python

result =

for item in item_list:

new_item = do_something_with(item)

python

result = [do_something_with(item) for item in item_list]

同樣的,如果你只是想要獲取乙個迭代器,你可以使用語法幾乎相通的生成器表示式。(你怎麼能不愛上python的一致性?)

python

result = (do_something_with(item) for item in item_list)

2. 函式

站在更高階、更函式化的變成方式考慮一下,如果你想對映乙個序列到另乙個序列,直接呼叫map函式。(也可用列表解析來替代。)

python

doubled_list = map(lambda x: x * 2, old_list)

如果你想使乙個序列減少到乙個元素,使用reduce

python

from functools import reduce

summation = reduce(lambda x, y: x + y, numbers)

另外,python中大量的內嵌功能可/會(我不知道這是好事還是壞事,你選乙個,不加這個句子有點難懂)消耗迭代器:

python

>>> a = list(range(10))

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> all(a)

false

>>> any(a)

true

>>> max(a)

>>> min(a)

>>> list(filter(bool, a))

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

>>> set(a)

>>> dict(zip(a,a))

>>> sorted(a, reverse=true)

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

>>> str(a)

'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'

>>> sum(a)

3. 抽取函式或者表示式

上面的兩種方法很好地處理了較為簡單的邏輯,那更複雜的邏輯怎麼辦呢?作為乙個程式設計師,我們會把困難的事情抽象成函式,這種方式也可以用在這裡。如果你寫下了這種**:

python

results =

for item in item_list:

# setups

# condition

# processing

# calculation

顯然你賦予了一段**太多的責任。為了改進,我建議你這樣做:

python

def process_item(item):

# setups

# condition

# processing

# calculation

return result

results = [process_item(item) for item in item_list]

巢狀的for迴圈怎麼樣?

python

results =

for i in range(10):

for j in range(i):

列表解析可以幫助你:

python

results = [(i, j)

for i in range(10)

for j in range(i)]

如果你要儲存很多的內部狀態怎麼辦呢?

python

# finding the max prior to the current item

a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]

results =

current_max = 0

for i in a:

current_max = max(i, current_max)

# results = [3, 4, 6, 6, 6, 9, 9, 9, 9, 9]

讓我們提取乙個表示式來實現這些:

python

def max_generator(numbers):

current_max = 0

for i in numbers:

current_max = max(i, current_max)

yield current_max

a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]

results = list(max_generator(a))

「等等,你剛剛在那個函式的表示式中使用了乙個for迴圈,這是欺騙!」

好吧,自作聰明的傢伙,試試下面的這個。

4. 你自己不要寫for迴圈,itertools會為你代勞

python

from itertools import accumulate

a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]

resutls = list(accumulate(a, max))

另外,如果你在迭代組合的序列,還有product(),permutations(),combinations()可以用。

1.大多數情況下是不需要寫for迴圈的。

2.應該避免使用for迴圈,這樣會使得**有更好的閱讀性。

1.再看一遍你的**,找出任何以前憑直覺寫下for迴圈的地方,再次思考一下,不用for迴圈再寫一遍是不是有意義的。

2.分享你很難不使用for迴圈的例子。

用迴圈代替游標

在sql的sp開發中,游標有不可或缺的作用。但是,一些不當的使用游標,會造成嚴重系統效能的下降,所有呢,很多的人就想找乙個方法,即能達到游標的功能,又對效能影響小一些。這就是本文要講的用迴圈代替游標。一般情況下,用光標的目的就是要達到乙個迴圈,可是我們要是以迴圈來作呢,如何來控制當前的變數值就是關鍵...

string用char代替方法

知道stl後,極度愛偷懶,一看到陣列要排序,就想用string,好把它放到set裡面去,但是用stl會極度慢。其實好好想想還他方法對多個字串排序,用結構體,陣列定義到裡面去,再重組運算子,因此,避開string,可以使用結構體包含陣列的方式,比如在map中,乙個int對應乙個string,可以把st...

php部分被棄用方法的代替方法

call user method 使用 call user func 替代 call user method array 使用 call user func array 替代 define syslog variables dl ereg 使用 preg match 替代 ereg replace ...