2016-10-20 109 views
1

有沒有更簡潔的方式來迭代迭代如果它有元素,或者做一些其他的事情,如果它沒有?是否有像「迭代迭代,如果它有元素,否則...」?

我的「問題」是Python,但我也會對其他語言感興趣。

目前我首先測試元件的數目:

In [1]: l=[] 

In [2]: if l: 
    ...:  for e in l: 
    ...:   print(e) 
    ...: else: 
    ...:  print("else") 
    ...: 
else 

for statement has an else

In [2]: for e in []: 
    ...:  print(e) 
    ...: else: 
    ...:  print("else") 
    ...: 
else 

但其 「套件」,當迭代完成,也執行(塊):

In [1]: for e in [1,2,3]: 
    ...:  print(e) 
    ...: else: 
    ...:  print("else") 
    ...: 
1 
2 
3 
else 

我意識到這裏沒有太多的收穫(一行和縮進水平),但我一個m好奇,如果這樣的事情存在。

+2

大多數時候你只是測試長度並提前退出:'如果不是l:#空的情況下,返回'。 –

+0

我已經包含第一個示例的測試輸出,以仔細檢查您在編輯之前指出的問題... – handle

+1

*「我還會對其他語言感興趣」* - 這將會有很多不同的方法在各種語言中,在這裏討論所有這些內容都是有點超出範圍的。 – deceze

回答

4

你們中的大多數只是測試長度和退出早的時間:

if not l: 
    # empty case 
    return # or raise exception 

無論如何,因爲迭代不會發生一個空的列表上,下面的內容也是足夠了,不需要else

if not l: 
    # empty case 
for i in l: 
    # only ever executed if there are any elements 

for ... else套件僅用於循環有用的退出早;對於完成的所有循環,執行else套件。如果使用break,則跳過else。這使得它不適合用於檢測空序列,因爲無論在沒有break語句的情況下元素的數量如何,它們的迭代都​​成功完成。

+0

太明顯了:-) – handle

0

既然你問其他語言,這裏是佳樂/菲羅Smalltalk中,因爲範式是足夠接近的Python:

你會寫是這樣的:

aCollection 
    ifEmpty: [Transcript cr; show: 'else'] 
    ifNotEmpty: [aCollection do: [:each | Transcript cr; show: each printString]]. 

你還可創建在收集新的方法:

ifNotEmptyDo: aBlock elseDo: elseBlock 
    self isEmpty ifTrue: [^elseBlock value]. 
    ^self do: aBlock 

然後使用它是這樣的:

aCollection 
    ifNotEmptyDo: [:each | Transcript cr; show: each printString] 
    elseDo: [Transcript cr; show: 'else']. 

注意的isEmpty被定義爲^self size = 0默認情況下,這是可能的懶惰或無限集合的異端......所以我提出這個新的定義:

isEmpty 
    self do: [:each |^false]. 
    ^true 

只是看到測試emptyness或執行循環或多或少是相同的任務;)

結論,在Smalltalk中有一個非常低的語法糖水平。
塊關閉啓用不同的,有條件的或重複的評估。
因此,像分支和循環以及這些組合的所有結構都只是以塊閉包爲參數的普通消息,您可以隨意添加自己的構造。
這個設施經常被濫用選擇器過度增值,因此需要新的構造來維護成本(更多的方法來實施,測試和學習新手等)。 )。讓我們記住:「小很漂亮」。

相關問題