首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Fortran中有没有与Python的for-else语句等效的语句?

在Fortran中有没有与Python的for-else语句等效的语句?
EN

Stack Overflow用户
提问于 2016-12-01 13:13:16
回答 6查看 528关注 0票数 3

在Fortran中有没有与Python的for-else语句等效的语句?

例如,下面的代码将数字列表排序到不同的范围。在Python中,它是:

代码语言:javascript
复制
absth = [1, 2, 3, 4, 5]
vals = [.1, .2, .5, 1.2, 3.5, 3.7, 16.8, 19.8, 135.60]


counts = [0] * len(absth)
for v in vals:
    for i, a in enumerate(absth):
        if v < a:
            counts[i] += 1
            break
    else:
        counts[-1] += 1

在Fortran中,这是一样的:

代码语言:javascript
复制
do iv = 1, nvals

  is_in_last_absth = .true.

  do ia = 1, nabsth - 1
    if vals(iv) < absth(ia) then
      counts(ia) = counts(ia) + 1
      is_in_last_absth = .false.
      exit
    end if
  end do

  if (is_in_last_absth) then
    counts(nabsth) = counts(nabsth) + 1
  end if

end do

但是,有没有一种方法可以不用使用is_in_last_absth,而用Python中的else之类的东西来代替它呢?

EN

回答 6

Stack Overflow用户

发布于 2016-12-01 18:45:40

没有与python构造直接等效。

但请注意,可以通过检查循环之后的do变量的值来检测具有计数循环控制的do循环的提前终止。

代码语言:javascript
复制
do iv = 1, nvals
  do ia = 1, nabsth - 1
    if (vals(iv) < absth(ia)) then
      counts(ia) = counts(ia) + 1
      exit
    end if
  end do

  ! If the loop terminates because it completes the iteration 
  ! count (and not because the exit statement is executed) then 
  ! the do variable is one step beyond the value it had 
  ! during the last iteration.
  if (ia == nabsth) then
    counts(nabsth) = counts(nabsth) + 1
  end if
end do

除了do循环之外,exit语句还可以跳出更多:

代码语言:javascript
复制
do iv = 1, nvals
  outer_block: block
    do ia = 1, nabsth - 1
      if (vals(iv) < absth(ia)) then
        counts(ia) = counts(ia) + 1
        exit outer_block
      end if
    end do

    counts(nabsth) = counts(nabsth) + 1
  end block outer_block
end do

循环语句可以循环该语句所嵌套的任何do构造:

代码语言:javascript
复制
outer_loop: do iv = 1, nvals
  do ia = 1, nabsth - 1
    if (vals(iv) < absth(ia)) then
      counts(ia) = counts(ia) + 1
      cycle outer_loop
    end if
  end do

  counts(nabsth) = counts(nabsth) + 1
end do outer_loop
票数 5
EN

Stack Overflow用户

发布于 2016-12-01 17:53:56

如果问题具体是关于将一系列数字分类,absth是每个分类的上限(除了最后一个没有上限的分类),那么我可能会这样写:

代码语言:javascript
复制
PROGRAM test

  IMPLICIT NONE

  INTEGER :: ix   
  INTEGER, DIMENSION(5) :: absth = [1, 2, 3, 4, 5]   
  REAL, DIMENSION(9) :: vals = [.1, .2, .5, 1.2, 3.5, 3.7, 16.8, 19.8, 135.60]   
  INTEGER, DIMENSION(SIZE(absth)+1) :: bins

  bins = 0

  DO ix = 1, SIZE(bins)-1
     bins(ix) = COUNT(vals<absth(ix))   
  END DO   
  bins(ix) = COUNT(vals)

  bins = bins-EOSHIFT(bins,-1)
  WRITE(*,*) 'bins = ', bins
  ! which writes  3  1  0  2  0  3

END PROGRAM test

然后,当我对逻辑正确感到满意时,我会将其转换为一个函数,并添加一些错误检查。

如果问题更一般,问重现Python的for-else结构的惯用Fortran (90后)方法是什么,这里也有答案。

票数 3
EN

Stack Overflow用户

发布于 2016-12-01 14:22:29

转到允许任意跳转的语句。特别是,编写for循环,后跟else块,然后是标记为continue的代码块。在循环中,如果条件为真,则跳转到标记为continue的。否则,for循环将正常终止,else块将被执行,然后是continue,这与python的for...else构造的语义完全匹配。

例如:

代码语言:javascript
复制
        INTEGER nabsth, nvals
        PARAMETER (nabsth=5, nvals=9)
        INTEGER absth(nabsth), counts(nabsth)
        REAL vals(nvals)
        DATA absth/1, 2, 3, 4, 5/
        DATA counts/0, 0, 0, 0, 0/
        DATA vals/.1, .2, .5, 1.2, 3.5, 3.7, 16.8, 19.8, 135.60/

        do iv = 1, nvals

          do ia = 1, nabsth - 1
            if (vals(iv) < absth(ia)) then
              counts(ia) = counts(ia) + 1
              goto 10
            end if
          end do
          counts(nabsth) = counts(nabsth) + 1
10        continue
        end do
        WRITE (*,*), counts
        end

产生

代码语言:javascript
复制
       3           1           0           2           3
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40903078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档