在Fortran中有没有与Python的for-else语句等效的语句?
例如,下面的代码将数字列表排序到不同的范围。在Python中,它是:
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中,这是一样的:
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之类的东西来代替它呢?
发布于 2016-12-01 18:45:40
没有与python构造直接等效。
但请注意,可以通过检查循环之后的do变量的值来检测具有计数循环控制的do循环的提前终止。
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语句还可以跳出更多:
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构造:
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发布于 2016-12-01 17:53:56
如果问题具体是关于将一系列数字分类,absth是每个分类的上限(除了最后一个没有上限的分类),那么我可能会这样写:
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后)方法是什么,这里也有答案。
发布于 2016-12-01 14:22:29
转到允许任意跳转的语句。特别是,编写for循环,后跟else块,然后是标记为continue的代码块。在循环中,如果条件为真,则跳转到标记为continue的。否则,for循环将正常终止,else块将被执行,然后是continue,这与python的for...else构造的语义完全匹配。
例如:
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产生
3 1 0 2 3https://stackoverflow.com/questions/40903078
复制相似问题