Python論理演算子完全ガイド – and・or・notの使い方とベストプラクティス

 

論理演算子とは?

Python の論理演算子は、複数の条件を組み合わせて論理的な判定を行うための演算子です。andornot の3つがあり、条件分岐やループ処理で複雑な条件を簡潔に記述できます。

基本的な論理演算子

1. and演算子(論理積)

and は両方の条件が真(True)の場合のみ真を返します。

# 基本的なand演算子
age = 25
income = 400000

if age >= 20 and income >= 300000:
    print("ローン審査に通りました")  # 出力される

# 複数条件の組み合わせ
score = 85
attendance = 90

if score >= 80 and attendance >= 85:
    print("優秀な成績です")  # 出力される

2. or演算子(論理和)

or はどちらか一方の条件が真の場合に真を返します。

# 基本的なor演算子
weather = "雨"
temperature = 15

if weather == "雨" or temperature < 10:
    print("外出を控えましょう")  # 出力される

# 複数の選択肢
day = "土曜日"

if day == "土曜日" or day == "日曜日":
    print("週末です")  # 出力される

3. not演算子(論理否定)

not は条件の真偽を反転させます。

# 基本的なnot演算子
is_logged_in = False

if not is_logged_in:
    print("ログインしてください")  # 出力される

# リストが空でないかチェック
data = []

if not data:
    print("データがありません")  # 出力される

論理演算子の真偽値表

1. and演算子の真偽値表

# and演算子のパターン
print(True and True)    # True
print(True and False)   # False
print(False and True)   # False
print(False and False)  # False

2. or演算子の真偽値表

# or演算子のパターン
print(True or True)    # True
print(True or False)   # True
print(False or True)   # True
print(False or False)  # False

3. not演算子の真偽値表

# not演算子のパターン
print(not True)   # False
print(not False)  # True
print(not 0)      # True
print(not 1)      # False

短絡評価(Short-circuit Evaluation)

1. and演算子の短絡評価

def check_positive(x):
    print(f"check_positive({x}) が呼ばれました")
    return x > 0

# 最初の条件がFalseなら、2番目は評価されない
result = False and check_positive(5)
print(result)  # False(check_positiveは呼ばれない)

# 最初の条件がTrueなら、2番目も評価される
result = True and check_positive(5)
# check_positive(5) が呼ばれました
print(result)  # True

2. or演算子の短絡評価

def expensive_operation():
    print("高コストな処理が実行されました")
    return True

# 最初の条件がTrueなら、2番目は評価されない
result = True or expensive_operation()
print(result)  # True(expensive_operationは呼ばれない)

# 最初の条件がFalseなら、2番目も評価される
result = False or expensive_operation()
# 高コストな処理が実行されました
print(result)  # True

複合的な論理演算

1. 複数の論理演算子の組み合わせ

# 複雑な条件の組み合わせ
age = 25
income = 500000
credit_score = 750

# 括弧を使って優先順位を明確に
if (age >= 20 and income >= 400000) or credit_score >= 800:
    print("特別ローンの対象です")

# より複雑な条件
is_student = False
has_job = True
parent_income = 600000

if (is_student and parent_income >= 500000) or (not is_student and has_job):
    print("申請可能です")

2. ド・モルガンの法則の活用

# ド・モルガンの法則: not(A and B) = (not A) or (not B)
x = 5
y = 10

# 等価な条件式
condition1 = not (x > 10 and y < 5)
condition2 = (not x > 10) or (not y < 5)
condition3 = (x <= 10) or (y >= 5)

print(condition1)  # True
print(condition2)  # True
print(condition3)  # True

実践的な使用例

1. ユーザー認証システム

def authenticate_user(username, password, is_active=True):
    valid_username = username and len(username) >= 3
    valid_password = password and len(password) >= 8
    
    if valid_username and valid_password and is_active:
        return "認証成功"
    elif not is_active:
        return "アカウントが無効です"
    else:
        return "認証失敗"

# 使用例
result = authenticate_user("user123", "password123", True)
print(result)  # 認証成功

2. データバリデーション

def validate_email(email):
    if not email:
        return False
    
    has_at = "@" in email
    has_dot = "." in email
    proper_length = 5 <= len(email) <= 50
    
    return has_at and has_dot and proper_length

# 使用例
emails = ["test@example.com", "invalid-email", "", "a@b.c"]
for email in emails:
    is_valid = validate_email(email)
    print(f"{email}: {'有効' if is_valid else '無効'}")

3. 営業時間の判定

from datetime import datetime

def is_business_hours():
    now = datetime.now()
    current_hour = now.hour
    is_weekday = now.weekday() < 5  # 0-4 が平日
    
    return is_weekday and 9 <= current_hour <= 17

def get_status_message():
    if is_business_hours():
        return "営業時間中です"
    else:
        return "営業時間外です"

print(get_status_message())

条件分岐での応用

1. 複数条件でのif文

def categorize_student(score, attendance):
    if score >= 90 and attendance >= 95:
        return "優秀"
    elif score >= 70 and attendance >= 80:
        return "良好"
    elif score >= 50 or attendance >= 60:
        return "普通"
    else:
        return "要改善"

# 使用例
students = [
    (95, 98),
    (75, 85),
    (45, 70),
    (30, 40)
]

for score, attendance in students:
    category = categorize_student(score, attendance)
    print(f"成績:{score}, 出席:{attendance}% → {category}")

2. 早期リターンパターン

def process_order(user_id, product_id, quantity):
    # 不正な値の早期チェック
    if not user_id or not product_id or quantity <= 0:
        return "無効な注文情報です"
    
    # 在庫チェック(例)
    stock = 100
    if quantity > stock:
        return "在庫不足です"
    
    # 正常処理
    return "注文を受け付けました"

# 使用例
result = process_order("user123", "prod456", 5)
print(result)  # 注文を受け付けました

リスト・辞書での論理演算

1. any()とall()関数の活用

# リスト内の要素に対する論理演算
numbers = [2, 4, 6, 8, 10]

# すべて偶数かチェック
all_even = all(num % 2 == 0 for num in numbers)
print(f"すべて偶数: {all_even}")  # True

# 10以上の数があるかチェック
has_large = any(num >= 10 for num in numbers)
print(f"10以上の数あり: {has_large}")  # True

2. 辞書での条件チェック

def check_user_permissions(user):
    is_admin = user.get("role") == "admin"
    is_active = user.get("is_active", False)
    has_permission = user.get("permissions", [])
    
    can_delete = is_admin or "delete" in has_permission
    can_access = is_active and (is_admin or has_permission)
    
    return {
        "can_delete": can_delete,
        "can_access": can_access
    }

# 使用例
user = {
    "role": "user",
    "is_active": True,
    "permissions": ["read", "write"]
}

permissions = check_user_permissions(user)
print(permissions)  # {'can_delete': False, 'can_access': True}

パフォーマンスの考慮事項

1. 効率的な条件の順序

def expensive_check():
    print("高コストな処理")
    return True

def cheap_check():
    print("軽い処理")
    return False

# 軽い処理を先に配置(短絡評価を活用)
if cheap_check() and expensive_check():
    print("両方とも真")
else:
    print("少なくとも一方が偽")  # 出力される

2. 条件の最適化

# 非効率な書き方
def check_range_bad(value):
    if value >= 0 and value <= 100:
        return True
    else:
        return False

# 効率的な書き方
def check_range_good(value):
    return 0 <= value <= 100

# 使用例
print(check_range_good(50))   # True
print(check_range_good(150))  # False

よくある間違いと対処法

1. 演算子の優先順位

# 間違いやすい例
x = 5
y = 10

# not の優先順位が高い
result1 = not x == y and True  # (not (x == y)) and True
result2 = not (x == y and True)  # not ((x == y) and True)

print(f"結果1: {result1}")  # True
print(f"結果2: {result2}")  # False

2. 真偽値の誤解

# Pythonの真偽値判定
falsy_values = [False, 0, "", [], {}, None]
truthy_values = [True, 1, "text", [1], {"key": "value"}, 42]

print("偽と評価される値:")
for value in falsy_values:
    if not value:
        print(f"  {repr(value)}")

print("真と評価される値:")
for value in truthy_values:
    if value:
        print(f"  {repr(value)}")

3. リストでの論理演算の注意点

# 空リストの扱い
def process_list(data):
    if not data:  # 空リストや None をチェック
        return "データがありません"
    
    if len(data) > 0 and all(isinstance(x, int) for x in data):
        return "整数リストです"
    
    return "混合データです"

# 使用例
print(process_list([]))        # データがありません
print(process_list([1, 2, 3])) # 整数リストです
print(process_list([1, "a"]))  # 混合データです

実践的なデザインパターン

1. ガード句パターン

def calculate_discount(customer_type, purchase_amount, is_member):
    # ガード句で早期リターン
    if not customer_type or purchase_amount <= 0:
        return 0
    
    if customer_type == "VIP" and is_member:
        return purchase_amount * 0.2
    elif customer_type == "regular" and is_member:
        return purchase_amount * 0.1
    elif purchase_amount >= 10000:
        return purchase_amount * 0.05
    
    return 0

# 使用例
discount = calculate_discount("VIP", 5000, True)
print(f"割引額: {discount}円")

2. 設定値の検証

class Config:
    def __init__(self, debug=False, port=8000, host="localhost"):
        self.debug = debug
        self.port = port
        self.host = host
    
    def is_valid(self):
        valid_port = 1 <= self.port <= 65535
        valid_host = self.host and isinstance(self.host, str)
        valid_debug = isinstance(self.debug, bool)
        
        return valid_port and valid_host and valid_debug
    
    def get_url(self):
        if not self.is_valid():
            return None
        
        protocol = "http" if not self.debug else "http"
        return f"{protocol}://{self.host}:{self.port}"

# 使用例
config = Config(debug=True, port=3000, host="0.0.0.0")
if config.is_valid():
    print(f"サーバーURL: {config.get_url()}")

まとめ

Python の論理演算子を効果的に使うポイント:

  • 基本演算子の理解: andornot の動作を正確に把握する
  • 短絡評価の活用: パフォーマンス向上のため軽い条件を先に配置
  • 括弧の使用: 複雑な条件では括弧で優先順位を明確にする
  • 真偽値の理解: Pythonの真偽値判定ルールを把握する
  • 可読性の重視: 複雑すぎる条件は関数に分離して可読性を保つ

論理演算子を適切に使いこなすことで、効率的で読みやすい条件処理が実現できます。

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座