有没有更好的方法来遍历这个列表?
Is there a more optimal way to loop through this list?
我已经声明了一份水果清单,例如:
def fruits = ["apple", "orange", "pineapple"]
并且我使用列表
for (fruit in fruits){
if(fruit=="orange"){
println("A delicious ${fruit}")
}
if(fruit=="pineapple"){
println("Another delicious ${fruit}")
}
if(fruit=="apple"){
println("More delicious ${fruit}"})
}
}
这行得通。但我只是想看看是否有更好的方法来达到相同的结果。
感谢您的帮助。
通常,对于此类问题,您有两种解决方法。我在这里使用 Python 作为示例来解释语法差异及其可能为您生成的结果。
for i in range(len(fruits)):
或者你用过的那个
for fruit in fruits:
分析字节码
[替代解决方案]
12 0 SETUP_LOOP 40 (to 43)
3 LOAD_GLOBAL 0 (range)
6 LOAD_GLOBAL 1 (len)
9 LOAD_FAST 0 (fruits)
12 CALL_FUNCTION 1
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 20 (to 42)
22 STORE_FAST 1 (i)
13 25 LOAD_GLOBAL 2 (print)
28 LOAD_FAST 0 (fruits)
31 LOAD_FAST 1 (i)
34 BINARY_SUBSCR
35 CALL_FUNCTION 1
38 POP_TOP
39 JUMP_ABSOLUTE 19
>> 42 POP_BLOCK
>> 43 LOAD_CONST 0 (None)
46 RETURN_VALUE
[你的解决方案]
17 0 SETUP_LOOP 24 (to 27)
3 LOAD_FAST 0 (fruits)
6 GET_ITER
>> 7 FOR_ITER 16 (to 26)
10 STORE_FAST 1 (fruit)
18 13 LOAD_GLOBAL 0 (print)
16 LOAD_FAST 1 (fruit)
19 CALL_FUNCTION 1
22 POP_TOP
23 JUMP_ABSOLUTE 7
>> 26 POP_BLOCK
>> 27 LOAD_CONST 0 (None)
30 RETURN_VALUE
这很清楚地表明,当涉及到循环本身时,您的解决方案已经优化得多。但是,您的块的这个问题是您到处都在使用 if 语句,这意味着即使循环已经找到您正在寻找的值,也会评估和检查每个语句。
一个更好的方法是使用 if-else 而不是 来进一步优化它。但是,与其使用嵌套的 if 语句,不如使用 switch 语句 完全替换它们,只要案例数量合适,就可以更快、更干净。
认为每一个 if 语句都会增加程序的复杂性,最好尽可能避免它们,同时避免更糟糕的 switch 语句。
您的代码高效但丑陋,因为它无法很好地扩展。如果修改列表,则还需要修改循环。使用现代语言 groovy,您可以这样写(如前所述):
def fruits = [
apple : { "A delicious $it" },
orange : { "Another delicious $it" },
pineapple : { "More delicious $it" }
]
fruits.each { fruit, action ->
println action(fruit)
}
与您的代码相比,这可能效率低下,因为它涉及地图,但如果我关心速度,我会选择另一种编程语言。
我已经声明了一份水果清单,例如:
def fruits = ["apple", "orange", "pineapple"]
并且我使用列表
for (fruit in fruits){
if(fruit=="orange"){
println("A delicious ${fruit}")
}
if(fruit=="pineapple"){
println("Another delicious ${fruit}")
}
if(fruit=="apple"){
println("More delicious ${fruit}"})
}
}
这行得通。但我只是想看看是否有更好的方法来达到相同的结果。
感谢您的帮助。
通常,对于此类问题,您有两种解决方法。我在这里使用 Python 作为示例来解释语法差异及其可能为您生成的结果。
for i in range(len(fruits)):
或者你用过的那个
for fruit in fruits:
分析字节码
[替代解决方案]
12 0 SETUP_LOOP 40 (to 43)
3 LOAD_GLOBAL 0 (range)
6 LOAD_GLOBAL 1 (len)
9 LOAD_FAST 0 (fruits)
12 CALL_FUNCTION 1
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 20 (to 42)
22 STORE_FAST 1 (i)
13 25 LOAD_GLOBAL 2 (print)
28 LOAD_FAST 0 (fruits)
31 LOAD_FAST 1 (i)
34 BINARY_SUBSCR
35 CALL_FUNCTION 1
38 POP_TOP
39 JUMP_ABSOLUTE 19
>> 42 POP_BLOCK
>> 43 LOAD_CONST 0 (None)
46 RETURN_VALUE
[你的解决方案]
17 0 SETUP_LOOP 24 (to 27)
3 LOAD_FAST 0 (fruits)
6 GET_ITER
>> 7 FOR_ITER 16 (to 26)
10 STORE_FAST 1 (fruit)
18 13 LOAD_GLOBAL 0 (print)
16 LOAD_FAST 1 (fruit)
19 CALL_FUNCTION 1
22 POP_TOP
23 JUMP_ABSOLUTE 7
>> 26 POP_BLOCK
>> 27 LOAD_CONST 0 (None)
30 RETURN_VALUE
这很清楚地表明,当涉及到循环本身时,您的解决方案已经优化得多。但是,您的块的这个问题是您到处都在使用 if 语句,这意味着即使循环已经找到您正在寻找的值,也会评估和检查每个语句。
一个更好的方法是使用 if-else 而不是 来进一步优化它。但是,与其使用嵌套的 if 语句,不如使用 switch 语句 完全替换它们,只要案例数量合适,就可以更快、更干净。
认为每一个 if 语句都会增加程序的复杂性,最好尽可能避免它们,同时避免更糟糕的 switch 语句。
您的代码高效但丑陋,因为它无法很好地扩展。如果修改列表,则还需要修改循环。使用现代语言 groovy,您可以这样写(如前所述):
def fruits = [
apple : { "A delicious $it" },
orange : { "Another delicious $it" },
pineapple : { "More delicious $it" }
]
fruits.each { fruit, action ->
println action(fruit)
}
与您的代码相比,这可能效率低下,因为它涉及地图,但如果我关心速度,我会选择另一种编程语言。