2016-10-20 78 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中有一个非常低的语法糖水平。
块关闭启用不同的,有条件的或重复的评估。
因此,像分支和循环以及这些组合的所有结构都只是以块闭包为参数的普通消息,您可以随意添加自己的构造。
这个设施经常被滥用选择器过度增值,因此需要新的构造来维护成本(更多的方法来实施,测试和学习新手等)。 )。让我们记住:“小很漂亮”。

相关问题