Julia 循环逻辑

文章目录

Julia 循环逻辑(while,for),不同于判断逻辑,循环逻辑(Repeated Evaluation)会在条件满足的情况下,重复地运行一段代码以实现数据迭代处理等功能。

在实现循环逻辑时,我们在考虑什么情况下需要重复执行的同时,也需要考虑什么情况下不再循环。这是在开发中不能忽略的两个对偶问题。

Julia提供了whilefor这两种循环结构的同时,还提供了breakcontinue两个关键字,以便对循环进行控制。通过设定与业务功能相关的控制变量,并结合这两个关键字,便可实现在特定情况下终止循环或继续循环。

while

基于关键字while的循环结构同if结构类似,也需要将逻辑表达式作为判断条件,基本语法如下:

        while条件表达式
          # 语句块
        end

只有在“条件表达式”为true时,while内部的语句块才会执行。

在while内部的语句运行到end时,会再次返回对条件进行判断,如果为false,则忽略while内部的语句块,直接跳到end处执行其后的其他语句。

为了对while循环进行动态控制,一般其判断表达式中有控制变量,而且能在内部语句块进行更新,从而可以修改下次判断条件的逻辑结果。例如:

julia> i = 1;               # 循环控制变量
julia> while i <= 5        # 循环条件
         print(i, " ")     # 处理过程
         global i += 1     # 改变控制变量的值,其中的global关键字后文会介绍
         end
1 2 3 4 5

若非如此,条件便始终不变,while就会变成死循环或无限循环。

当然,对于条件表达式结果恒定不变的无限循环,也可以在满足内部某条件时通过关键字break打断循环过程。例如:
Julia 循环逻辑

其中,虽然while的条件表达式始终为true,成为无限循环结构,但通过控制变量与break的结合使用,可在需要时退出循环。此例实现了与上例相似的功能,只是结果略有不同,有兴趣的读者可以对比研究一下。

关键字break能够强制循环退出,但在多层嵌套的循环中只会影响其所处的那一层,不会波及外层或内层循环结构。例如:

julia> i=1; j=1;
julia> while j <= 4
          while true
            print(i, " ")
            if i > 5        # 内层循环控制
              break         # 强制退出内层循环
            end
            global i += 1  # 修改内层循环的控制变量
          end
          global j += 1     # 修改外层循环的控制变量
          global i = 1      # 重置内层循环的控制变量
          println()         # 换行打印
        end
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6

例中break导致内层while循环只执行到i=6时跳出,但外层由j控制的while循环并没有受到break的任何影响,顺利执行了4次。

同样用于循环控制的continue关键字,功能不同于break,不是打断循环,而是让循环运行到其位置时停止执行后续语句,并立即跳转到条件表达式处重新判断,如果条件成立便会再次重入循环。例如:
Julia 循环逻辑

其中,循环控制变量i以10为上界,只要小于10便会不断运行循环体内的语句;但在i小于5的情况下,不会执行continue之后的代码,所以打印出的结果都是不小于5的数值。

for

另外一种循环由关键字for构建,与while的用法有很大的不同。在for循环中,控制循环的不再是条件表达式,而是遍历型表达式。其基本表述结构为:

        for遍历表达式
          # 语句块
        end

其中,“遍历表达式”需要可迭代数据结构的支持。

一般而言,在数集迭代时便会驱动循环体的语句块一次次地执行;而循环的次数便是数集中可遍历到的元素个数。同时,遍历表达式本身会提供循环变量,用于逐一提取数集中的元素值,以便循环内部进行相应的处理。

Julia中提供了三种基本的遍历表达方式,如下:

        for循环变量 = 可迭代数据集
          # 更多语句
        end

        for循环变量in可迭代数据集
          # 更多语句
        end

        for循环变量 ∈ 可迭代数据集
          # 更多语句
        end

其中,三个遍历操作符=、in及∈是等价的,可以任选一个。

所谓可迭代数据集,主要是指后面介绍的元组(Tuple)、字典(Dict)及集合(Set),或者数组(Array)及范围表达式(Range)等。为了叙述方便,这里作简单的说明:元组的形式为(1,2,3),一旦创建内部元素不能再变更;数组是多维数据序列,以中括号表达,例如[1,2,3]或[1 2 3]便是有三个元素的数组;而范围表达式则用于表达等差序列,是一种迭代器,例如1:10表示公差为1的整数序列,取值1到10共计10个元素。

下面我们以实例来了解for循环的使用,例如:

julia> for i = 1:5
          print(i, " ")
        end
1 2 3 4 5

julia> for i in 1:5
          print(i, " ")
        end
1 2 3 4 5

julia> for i ∈ 1:5
          print(i, " ")
        end
1 2 3 4 5

或者:

julia> for i = [1 2 3 4 5]
          print(i, " ")
        end
1 2 3 4 5

julia> for i in [1 2 3 4 5]
          print(i, " ")
        end
1 2 3 4 5

julia> for i ∈ [1 2 3 4 5]
          print(i, " ")
        end
1 2 3 4 5

又或者:

julia> for i = (1,2,3,4,5)
          print(i, " ")
        end
1 2 3 4 5

julia> for i in (1,2,3,4,5)
          print(i, " ")
        end
1 2 3 4 5

julia> for i ∈ (1,2,3,4,5)
          print(i, " ")
        end
1 2 3 4 5

在for循环中,还支持同时对多个数据集进行遍历,例如:
Julia 循环逻辑

而且遍历操作符也可以混用,例如:
Julia 循环逻辑

在这种多遍历的表达中,得到的循环变量组合实际是每个数据集的笛卡尔积。也正因如此,遍历操作的顺序影响着内部语句中循环变量的取值。如果更换遍历操作的顺序,将会得到不同的结果。例如:

julia> for j = (1,2,3,4,5), i=1:2
          print((i, j), " ")
        end
(1, 1) (2, 1) (1, 2) (2, 2) (1, 3) (2, 3) (1, 4) (2, 4) (1, 5) (2, 5)

julia> for j in 3:4, i = [1 2 3 4 5]
          print((i, j), " ")
        end
(1, 3) (2, 3) (3, 3) (4, 3) (5, 3) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4)

可见与上述的运行结果不同。其中的i或j虽然仍出自同一数集,但因为遍历顺序的不同,循环变量的组合出现了差异。

还有一点需要注意,每一个遍历表达式之间的分割符是逗号而非是分号。如果使用分号,则会产生出乎意料的结果。例如:

julia> for i=1:2; j=3:4
            print((i, j), " ")
          end
(1, 3:4)   (2, 3:4)

可见只执行了2次循环,而不是4次;而且j的值不再是元素,也没有实现笛卡尔积。这是因为i=1:2; j=3:4这种表达不再是遍历表达式,而是复合表达式。

当然,在for循环中,我们同样可以使用breakcontinue来控制循环的运行。例如:

julia> for i = 1:1000
            print(i, " ")
            if i >= 5
              break
            end
          end
  1 2 3 4 5

例中的i在遍历表达中可以取到1000个数值,但因内部的if语句要求i>=5时break(中断循环),所以该循环只实际执行了5次。再例如:

julia> for i = 1:10
            if i % 3 != 0
              continue               # 重新跳到for i = 1:10
            end
            println(i)
          end
  3
  6
  9

即只有在i是3的倍数的时候,才会将i的值打印出来。

另外,在for循环中,continue的运作与在while中的表现是相同的,也同样只会影响其所处的内层循环,不会波及外层循环。例如:

julia> for j = 1:5
            println("\nloop ", j)  # \n为换行符,便于查看结果
            for i = 1:10
              if i % 3 != 0
                continue             # 重新跳到for i = 1:10
              end
              print(i, " ")
            end
          end
loop 1
3 6 9
loop 2
3 6 9
loop 3
3 6 9
loop 4
3 6 9
loop 5
3 6 9

其中由j控制的外层循环完整地运行了5次,而由i控制的内层循环只在i为3的倍数时完整地运行了3次,但实际仍运行了10次。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!