3

Python の for-else ステートメントに相当する Fortran はありますか?

たとえば、次の例では、数値のリストをさまざまな範囲に並べ替えます。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

しかし、それを使用して Pythonis_in_last_absthのようなものに置き換える必要がない方法はありますか?else

4

6 に答える 6

5

その 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

exit ステートメントは、do ループ以外からもジャンプできます。

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

また、cycle ステートメントは、ステートメントがネストされている 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-01T10:45:40.103 に答える
2

GO TO ステートメントは、任意のジャンプを許可します。特に、for ループに続いて else ブロックを記述し、その後にラベル付きの continue を記述します。ループ内で、条件が true の場合、ラベルの付いた continue にジャンプします。それ以外の場合、for ループは正常に終了し、else ブロックが実行されてから続行され、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           3
于 2016-12-01T06:22:28.927 に答える
2

Python の for-else ブロックのelse部分は、すべての要素が処理されたときにのみ実行されるため、単純ifに最後の要素のステートメントを使用するのはどうですか? 例えば、

program main
    implicit none
    integer i, n
    print *, "n = ?" ; read(*,*) n

    do i = 1, 10
        if ( i <= n ) then
            print *, i
        else
            exit
        endif
        if ( i == 10 ) print *, "reached the final index"
    enddo

    print *, "done"
end program

おそらく対応する

n = int( input( "n = ? \n" ) )

for i in range( 1, 11 ):
    if i <= n:
        print( i )
    else:
        break
else:
    print( "reached the final index" )

print( "done" )

別の方法として、次のようなラベル付きのblock構成を使用することもできます。

program main
    implicit none
    integer i, n
    print *, "n = ?" ; read(*,*) n

    loop_i : block

      do i = 1, 10
          if ( i <= n ) then
              print *, i
          else
              exit loop_i
          endif
      enddo
      print *, "reached the final index"

    endblock loop_i

    print *, "done"
end program

Chap.20.1.7: 「Modern Fortran Explained (Metcalf et al) による」の「ほぼすべてのコンストラクトからの終了」および F2008 標準のChap.8.1.10 (ここから取得) によると、任意のラベル付きコンストラクトから終了しても問題ありません。block、などですがifassociate比較的新しいコンパイラが必要になる場合があります (gfortran-6 が機能しました)。exitに関する IBM の man ページも役立ちます。

于 2016-12-01T10:30:12.813 に答える
0

私の知る限りでは、Python は for-else ステートメントを持つ唯一の (または非常に少数の) 言語です。いいえ、Fortran にはありません。

于 2016-12-01T05:15:22.397 に答える
0

たまにはGOTOもいい。WHERE ELSEWHERE が役立つ場合があります...

do iv = 1, nvals

  is_in_last_absth = .true.
  Mask = .FALSE.
  Mask(1:(nabsth - 1)) = .TRUE.)
  Mask2 = .FALSE.
  WHERE(MASK)
    WHERE( vals(iv) < absth)
      mask2 = .TRUE.
    ENDWHERE

    WHERE(Mask2)
      Count = Count + 1
    ELSE
      LastCount = LastCount + 1
    ENDWHERE

  END WHERE
end do

count(2:(n-1)) = count(2:(n-1))+ lastcount(1:(n))
于 2016-12-01T22:19:17.973 に答える