LoginSignup
1
4

More than 3 years have passed since last update.

VBAユーザがPython・Rを使ってみた:繰り返し処理

Last updated at Posted at 2021-01-15

はじめに

機械学習の勉強を始めたVBAユーザです。
備忘録としてPython・Rの文法をVBAと比較しながらまとめていきたいと思います。

目次

繰り返し処理

今回は、繰り返し処理(ループ処理)についてまとめます。

for文

まずは、for文です。

シンプルな例

シンプルなfor文の例です。

Python

Python3
# for文
for i in range(5):
    print(i)
# 0
# 1
# 2
# 3
# 4
print(range(5))       # range(0, 5)
print(type(range(5))) # <class 'range'>
print(list(range(5))) # [0, 1, 2, 3, 4]

Pythonではfor文のブロックをインデント(字下げ)で表現します。
range(5)は 0,1,2,3,4 という整数を順番に返すイテラブルオブジェクト(iterable object)(反復可能オブジェクト)で、list(range(5)) でリスト[0, 1, 2, 3, 4] になります。

R

R
for (i in 0:4) {
  print(i)
}
# [1] 0
# [1] 1
# [1] 2
# [1] 3
# [1] 4
print(0:4)   # 0 1 2 3 4

0:4は 0 から 4 までの整数値のベクトルです。

VBA

VBA
For i = 0 To 4
    Debug.Print i
Next i
' 0
' 1
' 2
' 3
' 4

他の例

Python

Python3
Ns = [2, 3, 5, 7, 11]
for i in range(len(Ns)):
    print(Ns[i])
# 2
# 3
# 5
# 7
# 11

Ns = [2, 3, 5, 7, 11]
for n in Ns:
    print(n)
# 2
# 3
# 5
# 7
# 11

Pythonでは、リストもイテラブルオブジェクトなので、inの後に指定できます。

R

R
Ns <- c(2, 3, 5, 7, 11)
for (i in 1:length(Ns)) {
  print(Ns[i])
}
# [1] 2
# [1] 3
# [1] 5
# [1] 7
# [1] 11

Ns <- c(2, 3, 5, 7, 11)
for (n in Ns) {
  print(n)
}
# [1] 2
# [1] 3
# [1] 5
# [1] 7
# [1] 11

Rでも、inの後にベクトルを指定できます。

VBA

VBA
A = Array(2, 3, 5, 7, 11)
For i = LBound(A) To UBound(A)
    Debug.Print A(i)
Next i
' 2
' 3
' 5
' 7
' 11

VBAで、A = Array(2, 3, 5, 7, 11) と書くと、配列Aのインデックスは(デフォルトの設定では)0から4の整数になります。LBound(A)は配列Aの最小のインデックス(ここでは0)、UBound(A)は配列Aの最大のインデックス(ここでは4)を返します。

さらに

Pythonではこのような書き方もできます。

enumerate関数
enumerate関数は、イテラブルオブジェクトに対して(要素番号, 要素) の形のタプルを1つずつ返すイテラブルオブジェクトを返す組み込み関数です。

Python

Python3
Ns = [2, 3, 5, 7, 11]
for i, n in enumerate(Ns):
    print('Ns[' + str(i) + '] = ' + str(n))
# Ns[0] = 2
# Ns[1] = 3
# Ns[2] = 5
# Ns[3] = 7
# Ns[4] = 11

Ns = [2, 3, 5, 7, 11]
for i, n in enumerate(Ns):
    print('Ns[{}] = {}'.format(i, n))
# Ns[0] = 2
# Ns[1] = 3
# Ns[2] = 5
# Ns[3] = 7
# Ns[4] = 11

同じことをRとVBAで書くならこうなります。
R

R
Ns <- c(2, 3, 5, 7, 11)
for (i in 1:length(Ns)) {
  n = Ns[i]
  cat(paste0("Ns[", i, "] = ", n, "\n"))
}
# Ns[1] = 2
# Ns[2] = 3
# Ns[3] = 5
# Ns[4] = 7
# Ns[5] = 11

VBA

VBA
A = Array(2, 3, 5, 7, 11)
For i = LBound(A) To UBound(A)
    Debug.Print "Ns[" & CStr(i) & "] = " & Str(A(i))
Next i
' Ns [0] = 2
' Ns [1] = 3
' Ns [2] = 5
' Ns [3] = 7
' Ns [4] = 11

zip関数
zip関数は、複数のイテラブルオブジェクトに対してそれぞれからの要素のペアを1つずつ返すイテラブルオブジェクトを返す組み込み関数です。

Python

Python3
numbers = list(range(5))
alphabets = 'abcde'
hiraganas = 'あいうえお'
for n, s, h in zip(numbers, alphabets, hiraganas):
    print('{}-{}-{}'.format(n, s, h))
# 0-a-あ
# 1-b-い
# 2-c-う
# 3-d-え
# 4-e-お

while文

次は、while文です。

Python

Python3
i = 0
while i < 5:
    print(i)
    i = i + 1
# 0
# 1
# 2
# 3
# 4

i = 0
while i < 5:
    print(i)
    i += 1
# 0
# 1
# 2
# 3
# 4

i = i + 1は複合代入演算子+=を使ってi += 1とも書けます。

R

R
i <- 0
while (i < 5) {
  print(i)
  i = i + 1
}
# [1] 0
# [1] 1
# [1] 2
# [1] 3
# [1] 4

VBA

VBA
i = 0
Do While i < 5
    Debug.Print i
    i = i + 1
Loop
' 0
' 1
' 2
' 3
' 4

VBAでは、Whileの他にUntilもあります。

VBA
i = 0
Do Until i = 5
    Debug.Print i
    i = i + 1
Loop
' 0
' 1
' 2
' 3
' 4

同じことをPythonとRで書くならこうなります。
Python

Python3
i = 0
while not i == 5:
    print(i)
    i = i + 1
# 0
# 1
# 2
# 3
# 4

R

R
i <- 0
while (!(i == 5)) {
  print(i)
  i = i + 1

}
# [1] 0
# [1] 1
# [1] 2
# [1] 3
# [1] 4

ループの終了

途中でループを抜ける(繰り返し処理を終了する)方法です。

Python

Python3
for i in range(5):
    if i == 2:
        break
    print(i)
# 0
# 1

R

R
for (i in 0:4) {
  if (i == 2) {
    break
  }
  print(i)
}
# [1] 0
# [1] 1

VBA

VBA
For i = 0 To 4
    If i = 2 Then
        Exit For
    End If
    Debug.Print i
Next i
' 0
' 1

VBAでループを抜けるには、Forループの場合はExit For、Doループの場合はExit Doを使います。

ループのスキップ

途中のループを飛ばして(スキップして)次のループに移る(次の繰り返し処理に進む)方法です。

Python

Python3
for i in range(5):
    if i == 2:
        continue
    print(i)
# 0
# 1
# 3
# 4

R

R
for (i in 0:4) {
  if (i == 2) {
    next
  }
  print(i)
}
# [1] 0
# [1] 1
# [1] 3
# [1] 4

VBA

VBA
For i = 0 To 4
    If i = 2 Then
        GoTo continue
    End If
    Debug.Print i
continue:
Next i
' 0
' 1
' 3
' 4

VBAにはPythonのcontinue文やRのnext文のようなループをスキップする文はありません。どうしても使いたいならGoToを使います。

その他

Rにはrepeat文というのもありますが、これはwhile (TRUE)while文の条件式にTRUE(常に真)を入れたもの)と同じことですので、あまり使い道がなさそうです。

R

R
i <- 0
repeat {
  if (i == 2) {
    break
  }
  print(i)
  i = i + 1
}
# [1] 0
# [1] 1

i <- 0
while (TRUE) {
  if (i == 2) {
    break
  }
  print(i)
  i = i + 1
}
# [1] 0
# [1] 1

同じことをPythonとVBAで書くならこうなります。

Python

Python3
i = 0
while True:
    if i == 2:
        break
    print(i)
    i += 1
# 0
# 1

VBA

VBA
i = 0
Do While True
    If i = 2 Then
        Exit Do
    End If
    Debug.Print i
    i = i + 1
Loop
' 0
' 1

まとめ

一覧

各言語で使用する書き方等を一覧にまとめます。

Python R VBA
for文 for i in ...:
 ...
for (i in ...) {
 ...
}
For i = ... To ...
 ...
Next i
while文 while ...:
 ...
while (...) {
 ...
}
Do While ...
 ...
Loop
until文 while not ...:
 ...
while (!(...)) {
 ...
}
Do Until ...
 ...
Loop
repeat文 while True:
 ...
repeat {
 ...
}
Do While True
 ...
Loop
break文 break break Exit For
Exit Do
continue文 continue next

プログラム全体

参考までに使ったプログラムの全体を示します。

Python

Python3
# for文
for i in range(5):
    print(i)
# 0
# 1
# 2
# 3
# 4
print(range(5))       # range(0, 5)
print(type(range(5))) # <class 'range'>
print(list(range(5))) # [0, 1, 2, 3, 4]

Ns = [2, 3, 5, 7, 11]
for i in range(len(Ns)):
    print(Ns[i])
# 2
# 3
# 5
# 7
# 11

Ns = [2, 3, 5, 7, 11]
for n in Ns:
    print(n)
# 2
# 3
# 5
# 7
# 11

Ns = [2, 3, 5, 7, 11]
for i, n in enumerate(Ns):
    print('Ns[' + str(i) + '] = ' + str(n))
# Ns[0] = 2
# Ns[1] = 3
# Ns[2] = 5
# Ns[3] = 7
# Ns[4] = 11

Ns = [2, 3, 5, 7, 11]
for i, n in enumerate(Ns):
    print('Ns[{}] = {}'.format(i, n))
# Ns[0] = 2
# Ns[1] = 3
# Ns[2] = 5
# Ns[3] = 7
# Ns[4] = 11

numbers = list(range(5))
alphabets = 'abcde'
hiraganas = 'あいうえお'
for n, s, h in zip(numbers, alphabets, hiraganas):
    print('{}-{}-{}'.format(n, s, h))
# 0-a-あ
# 1-b-い
# 2-c-う
# 3-d-え
# 4-e-お

# while文
i = 0
while i < 5:
    print(i)
    i = i + 1
# 0
# 1
# 2
# 3
# 4

i = 0
while i < 5:
    print(i)
    i += 1
# 0
# 1
# 2
# 3
# 4

# untilの代わり
i = 0
while not i == 5:
    print(i)
    i = i + 1
# 0
# 1
# 2
# 3
# 4

# break文
for i in range(5):
    if i == 2:
        break
    print(i)
# 0
# 1

# continue文
for i in range(5):
    if i == 2:
        continue
    print(i)
# 0
# 1
# 3
# 4

# repeat文の代わり
i = 0
while True:
    if i == 2:
        break
    print(i)
    i += 1
# 0
# 1

R

R
# for文
for (i in 0:4) {
  print(i)
}
# [1] 0
# [1] 1
# [1] 2
# [1] 3
# [1] 4
print(0:4)   # 0 1 2 3 4

Ns <- c(2, 3, 5, 7, 11)
for (i in 1:length(Ns)) {
  print(Ns[i])
}
# [1] 2
# [1] 3
# [1] 5
# [1] 7
# [1] 11

Ns <- c(2, 3, 5, 7, 11)
for (n in Ns) {
  print(n)
}
# [1] 2
# [1] 3
# [1] 5
# [1] 7
# [1] 11

Ns <- c(2, 3, 5, 7, 11)
for (i in 1:length(Ns)) {
  n = Ns[i]
  cat(paste0("Ns[", i, "] = ", n, "\n"))
}
# Ns[1] = 2
# Ns[2] = 3
# Ns[3] = 5
# Ns[4] = 7
# Ns[5] = 11

# while文
i <- 0
while (i < 5) {
  print(i)
  i = i + 1
}
# [1] 0
# [1] 1
# [1] 2
# [1] 3
# [1] 4

# untilの代わり
i <- 0
while (!(i == 5)) {
  print(i)
  i = i + 1

}
# [1] 0
# [1] 1
# [1] 2
# [1] 3
# [1] 4

# break文
for (i in 0:4) {
  if (i == 2) {
    break
  }
  print(i)
}
# [1] 0
# [1] 1

# next文
for (i in 0:4) {
  if (i == 2) {
    next
  }
  print(i)
}
# [1] 0
# [1] 1
# [1] 3
# [1] 4

# repeat文
i <- 0
repeat {
  if (i == 2) {
    break
  }
  print(i)
  i = i + 1
}
# [1] 0
# [1] 1

i <- 0
while (TRUE) {
  if (i == 2) {
    break
  }
  print(i)
  i = i + 1
}
# [1] 0
# [1] 1

VBA

VBA
Sub test_repeat()
Dim i As Integer
Dim A As Variant

' for文
For i = 0 To 4
    Debug.Print i
Next i
' 0
' 1
' 2
' 3
' 4

A = Array(2, 3, 5, 7, 11)
For i = LBound(A) To UBound(A)
    Debug.Print A(i)
Next i
' 2
' 3
' 5
' 7
' 11

A = Array(2, 3, 5, 7, 11)
For i = LBound(A) To UBound(A)
    Debug.Print "Ns[" & CStr(i) & "] = " & Str(A(i))
Next i
' Ns [0] = 2
' Ns [1] = 3
' Ns [2] = 5
' Ns [3] = 7
' Ns [4] = 11

' while文
i = 0
Do While i < 5
    Debug.Print i
    i = i + 1
Loop
' 0
' 1
' 2
' 3
' 4

' until文
i = 0
Do Until i = 5
    Debug.Print i
    i = i + 1
Loop
' 0
' 1
' 2
' 3
' 4

' ループからExit
For i = 0 To 4
    If i = 2 Then
        Exit For
    End If
    Debug.Print i
Next i
' 0
' 1
' Doループの場合は、Exit Do

' GoToを使ってcontinue文をVBAで実現
For i = 0 To 4
    If i = 2 Then
        GoTo continue
    End If
    Debug.Print i
continue:
Next i
' 0
' 1
' 3
' 4

' repeat文の代わり
i = 0
Do While True
    If i = 2 Then
        Exit Do
    End If
    Debug.Print i
    i = i + 1
Loop
' 0
' 1

End Sub

参考

1
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4