LoginSignup
1
2

More than 3 years have passed since last update.

VBAユーザがPython・Rを使ってみた:条件分岐

Last updated at Posted at 2021-01-17

はじめに

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

目次

条件分岐

今回は、条件分岐についてです。
コメントをいただいて、追記しました。

if文

条件分岐(主に、if文)についてです。

Python

Python3
x = 0
if x == 0:
    print(0)
# 0

if x == 0:
    print(0)
else:
    print(1)
# 0

if x == 0:
    print(0)
elif x == 1:
    print(1)
elif x == 2:
    print(2)
else:
    print(3)
# 0

if x in (0,1,2):
    print(x)
else:
    print(3)
# 0

Pythonにはswitch文、case文はなさそうです。
なお、Pythonでは、If文のまとまり(ブロック)を(次のRのように{}で囲んだり、VBAのようにIfではじまってEnd Ifで閉じたり、というような方法ではなく)インデント(字下げ)で表現します(If文に限らず、他の制御構文(繰り返しのFor文)でも同様です。)。

R

R
x <- 0
if (x == 0) {
  print(0)
}
# 0

if (x == 0) {
  print(0)
} else {
  print(1)
}
# 0

if (x == 0) {
  print(0)
} else if (x == 1) {
  print(1)
} else if (x == 2) {
  print(2)
} else {
  print(3)
}
# 0

if (x %in% c(0,1,2)) {
  print(x)
} else {
  print(3)
}

Rには、switch関数がありますが、使いづらそうです(参考:R-Tips)。

VBA

VBA
x = 0
If x = 0 Then
    Debug.Print 0
End If
' 0

If x = 0 Then
    Debug.Print 0
Else
    Debug.Print 1
End If
' 0

If x = 0 Then
    Debug.Print 0
ElseIf x = 1 Then
    Debug.Print 1
ElseIf x = 2 Then
    Debug.Print 2
Else
    Debug.Print 3
End If
' 0

Select Case x
    Case 0
        Debug.Print 0
    Case 1
        Debug.Print 1
    Case 2
        Debug.Print 2
    Case Else
        Debug.Print 3
End Select
' 0

Select Case x
    Case 0, 1, 2
        Debug.Print x
    Case Else
        Debug.Print 3
End Select
' 0

Select Case x
    Case 0 To 2
        Debug.Print x
    Case Else
        Debug.Print 3
End Select
'0

Select Case x
    Case Is <= 2
        Debug.Print x
    Case Else
        Debug.Print 3
End Select
' 0

Debug.Print Switch(x = 0, 0)
' 0
Debug.Print Switch(x = 0, 0, 1, 1)
' 0
Debug.Print Switch(x = 0, 0, x = 1, 1, x = 2, 2, True, 3)
' 0
Debug.Print Switch(x <= 2, x, True, 3)
' 0

VBAにはSelect Case文があります。Switch関数もあります。

case文の実現

コメントをいただいて追記しました。)
Python、Rにはcase文がありませんが、標準機能を使って実現できます。

例として、日本語の曜日(aaa)を英語の曜日(ddd)に変換して出力することを考えます1

aaa aaaa ddd dddd
日曜日 Sun Sunday
月曜日 Mon Monday
火曜日 Tue Tuesday
水曜日 Wed Wednesday
木曜日 Thu Thursday
金曜日 Fri Friday
土曜日 Sat Saturday

VBA
VBAでは、Select Case文やSwitch関数を使って書くことができます。

VBA
s = "金"

Select Case s
    Case "日": Debug.Print "Sun"
    Case "月": Debug.Print "Mon"
    Case "火": Debug.Print "Tue"
    Case "水": Debug.Print "Wed"
    Case "木": Debug.Print "Thu"
    Case "金": Debug.Print "Fri"
    Case "土": Debug.Print "Sat"
    Case Else: Debug.Print "not found"
End Select
' Fri

Debug.Print Switch(s = "日", "Sun", _
                   s = "月", "Mon", _
                   s = "火", "Tue", _
                   s = "水", "Wed", _
                   s = "木", "Thu", _
                   s = "金", "Fri", _
                   s = "土", "Sat", _
                   True, "not found")
' Fri

これと同じことを、Python、Rの標準機能で実現してみます。

Python
Pythonでは、リスト(list)を使って次のように実現できます。

Python3
aaa = ['日', '月', '火', '水', '木', '金', '土']
ddd = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']

s = '金'
t = '銀'
print(s in aaa)          # True
print(t in aaa)          # False
print(aaa.index(s))      # 5
# print(aaa.index(t))    # エラー
print(ddd[aaa.index(s)]) # Fri

def aaa_to_ddd(value):
    if value in aaa:
        return ddd[aaa.index(value)]
    else:
        return 'not found'
print(aaa_to_ddd(s))   # Fri
print(aaa_to_ddd(t))   # not found

def print_ddd(value):
    if value in aaa:
        print(ddd[aaa.index(value)])
    else:
        print('not found')
print_ddd(s)   # Fri
print_ddd(t)   # not found

Pythonでは、辞書(dictionary)を使っても実現できます。こちらの方が簡単に書けます。

Python3
aaa = ['日', '月', '火', '水', '木', '金', '土']
ddd = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
aaa_ddd = dict(zip(aaa, ddd))   # 辞書
print(aaa_ddd)
# {'日': 'Sun', '月': 'Mon', '火': 'Tue', '水': 'Wed', '木': 'Thu', '金': 'Fri', '土': 'Sat'}

s = '金'
t = '銀'
print(aaa_ddd[s])     # Fri
# print(aaa_ddd[t])   # エラー
print(aaa_ddd.get(s)) # Fri
print(aaa_ddd.get(t)) # None

def aaa_to_ddd(value):
    if value in aaa:
        return aaa_ddd[value]
    else:
        return 'not found'
print(aaa_to_ddd(s))   # Fri
print(aaa_to_ddd(t))   # not found

def aaa_to_ddd(value):
    if value in aaa:
        return aaa_ddd.get(value)
    else:
        return 'not found'
print(aaa_to_ddd(s))   # Fri
print(aaa_to_ddd(t))   # not found

def aaa_to_ddd(value):
    return aaa_ddd.get(value, 'not found')
print(aaa_to_ddd(s))   # Fri
print(aaa_to_ddd(t))   # not found

def print_ddd(value):
    print(aaa_ddd.get(value, 'not found'))
print_ddd(s)   # Fri
print_ddd(t)   # not found

R
Rでは文字列ベクトルを使って実現できます。

R
aaa = c("日", "月", "火", "水", "木", "金", "土")
ddd = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

s <- "金"
t <- "銀"
s %in% aaa   # TRUE
t %in% aaa   # FALSE
aaa == s     # FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
aaa == t     # FALSE FALSE FALSE FALSE FALSE FALSE FALSE
which(aaa == s)      # 6
which(aaa == t)      # integer(0)
aaa[which(aaa == s)] # "金"
aaa[which(aaa == t)] # character(0)
aaa[aaa == s]        # "金"
aaa[aaa == t]        # character(0)

aaa_to_ddd <- function(value) {
  if (value %in% aaa) {
    return(ddd[aaa == value])   # ddd[aaa == value][1]
  } else {
    return("not found")
  }
}
aaa_to_ddd(s)   # "Fri"
aaa_to_ddd(t)   # "not found"

print_ddd <- function(value) {
  if (value %in% aaa) {
    print(ddd[aaa == value])
  } else {
    print("not found")
  }
}
print_ddd(s)   # "Fri"
print_ddd(t)   # "not found"

VBA

VBA
Function aaa_to_ddd_1(value As String) As String
' Case文を使って
Select Case value
    Case "日": aaa_to_ddd_1 = "Sun"
    Case "月": aaa_to_ddd_1 = "Mon"
    Case "火": aaa_to_ddd_1 = "Tue"
    Case "水": aaa_to_ddd_1 = "Wed"
    Case "木": aaa_to_ddd_1 = "Thu"
    Case "金": aaa_to_ddd_1 = "Fri"
    Case "土": aaa_to_ddd_1 = "Sat"
    Case Else: aaa_to_ddd_1 = "not found"
End Select
End Function

Function aaa_to_ddd_2(value As String) As String
' Switch関数を使って
Dim v As Variant
v = Switch(value = "日", "Sun", _
           value = "月", "Mon", _
           value = "火", "Tue", _
           value = "水", "Wed", _
           value = "木", "Thu", _
           value = "金", "Fri", _
           value = "土", "Sat")
If IsNull(v) Then
    v = "not found"
End If
aaa_to_ddd_2 = v
End Function

Function aaa_to_ddd_3(value As String) As String
' 配列を使って
Dim aaa As Variant
Dim ddd As Variant
Dim i As Integer
Dim s As String
aaa = Array("日", "月", "火", "水", "木", "金", "土")
ddd = Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
s = "not found"
For i = LBound(aaa) To UBound(aaa)
    If value = aaa(i) Then
        s = ddd(i)
    End If
Next i
aaa_to_ddd_3 = s
End Function

Sub print_ddd(value As String)
' Case文を使って
Select Case value
    Case "日": Debug.Print "Sun"
    Case "月": Debug.Print "Mon"
    Case "火": Debug.Print "Tue"
    Case "水": Debug.Print "Wed"
    Case "木": Debug.Print "Thu"
    Case "金": Debug.Print "Fri"
    Case "土": Debug.Print "Sat"
    Case Else: Debug.Print "not found"
End Select
End Sub

Sub test_case()

Dim s As String
Dim t As String

s = "金"
Select Case s
    Case "日": Debug.Print "Sun"
    Case "月": Debug.Print "Mon"
    Case "火": Debug.Print "Tue"
    Case "水": Debug.Print "Wed"
    Case "木": Debug.Print "Thu"
    Case "金": Debug.Print "Fri"
    Case "土": Debug.Print "Sat"
    Case Else: Debug.Print "not found"
End Select
' Fri

Debug.Print Switch(s = "日", "Sun", _
                   s = "月", "Mon", _
                   s = "火", "Tue", _
                   s = "水", "Wed", _
                   s = "木", "Thu", _
                   s = "金", "Fri", _
                   s = "土", "Sat", _
                   True, "not found")
' Fri

s = "金"
t = "銀"

Debug.Print aaa_to_ddd_1(s)   ' Fri
Debug.Print aaa_to_ddd_2(s)   ' Fri
Debug.Print aaa_to_ddd_3(s)   ' Fri
Debug.Print aaa_to_ddd_1(t)   ' not found
Debug.Print aaa_to_ddd_2(t)   ' not found
Debug.Print aaa_to_ddd_3(t)   ' not found

Call print_ddd(s)   ' Fri
Call print_ddd(t)   ' not found

End Sub

まとめ

一覧

各言語で使用するステートメント等を一覧にまとめます。比較のために、EXCELでの計算も示しました。

条件分岐

Python R VBA EXCEL
if文 if P:
 ...
elif Q:
 ...
elif R:
 ...
else:
 ...
if (P) {
 ...
} else if (Q) {
 ...
} else if (R) {
 ...
} else {
 ...
}
If P Then
 ...
ElseIf Q Then
 ...
ElseIf R Then
 ...
Else
 ...
End If
=IF(P,...,
IF(Q,...,
IF(R,...,
...)))
switch文 Select Case X
Case p
 ...
Case q
 ...
Case r
 ...
Case Else
 ...
End Select
=SWITCH(X,
p,...,
q,...,
r,...,
...)

プログラム全体

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

Python

Python3
# 条件分岐
x = 0
if x == 0:
    print(0)
# 0

if x == 0:
    print(0)
else:
    print(1)
# 0

if x == 0:
    print(0)
elif x == 1:
    print(1)
elif x == 2:
    print(2)
else:
    print(3)
# 0

if x in (0,1,2):
    print(x)
else:
    print(3)
# 0

R

R
# 条件分岐(If)
x <- 0
if (x == 0) {
  print(0)
}
# 0

if (x == 0) {
  print(0)
} else {
  print(1)
}
# 0

if (x == 0) {
  print(0)
} else if (x == 1) {
  print(1)
} else if (x == 2) {
  print(2)
} else {
  print(3)
}
# 0

if (x %in% c(0,1,2)) {
  print(x)
} else {
  print(3)
}
# 0

VBA

VBA
Sub test_conditional_branch()
Dim x As Integer

' 条件分岐
x = 0
If x = 0 Then
    Debug.Print 0
End If
' 0

If x = 0 Then
    Debug.Print 0
Else
    Debug.Print 1
End If
' 0

If x = 0 Then
    Debug.Print 0
ElseIf x = 1 Then
    Debug.Print 1
ElseIf x = 2 Then
    Debug.Print 2
Else
    Debug.Print 3
End If
' 0

Select Case x
    Case 0
        Debug.Print 0
    Case 1
        Debug.Print 1
    Case 2
        Debug.Print 2
    Case Else
        Debug.Print 3
End Select
' 0

Select Case x
    Case 0, 1, 2
        Debug.Print x
    Case Else
        Debug.Print 3
End Select
' 0

Select Case x
    Case 0 To 2
        Debug.Print x
    Case Else
        Debug.Print 3
End Select
'0

Select Case x
    Case Is <= 2
        Debug.Print x
    Case Else
        Debug.Print 3
End Select
' 0

Debug.Print Switch(x = 0, 0)
' 0
Debug.Print Switch(x = 0, 0, 1, 1)
' 0
Debug.Print Switch(x = 0, 0, x = 1, 1, x = 2, 2, True, 3)
' 0
Debug.Print Switch(x <= 2, x, True, 3)
' 0

End Sub

参考


  1. "aaa","aaaa","ddd","dddd" はExcelの書式の表示形式の文字列です。 

1
2
5

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
2