Python is演算子とは?同じオブジェクトかを確認する方法

Python is演算子の基本的な使い方を初心者向けに解説。==演算子との違いから、None判定、オブジェクト同一性の確認まで実践的な使い方を紹介します。

Learning Next 運営
18 分で読めます

Python is演算子とは?同じオブジェクトかを確認する方法

みなさん、Pythonで値を比較するとき、困ったことはありませんか?

==は知ってるけど、isって何?」「同じなのに結果が違う?」「なんでNoneにはisを使うの?」

こんな疑問を感じたことありますよね。

実は、Pythonにはis演算子という特別な比較方法があります。 これを理解すると、もっと正確で効率的なプログラムが書けるようになりますよ。

この記事では、is演算子の基本から実践的な使い方まで、わかりやすく解説していきます。 ==演算子との違いもバッチリ理解できるようになります!

is演算子って何?

is演算子は、2つのオブジェクトが「まったく同じもの」かどうかを確認する演算子です。

簡単に言うと、メモリ上の同じ場所を指しているかをチェックしてくれます。

==演算子との違いを知ろう

まずは実際に動かして、違いを見てみましょう。

# 値の比較(==演算子)
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True(値が同じ)
print(a is b) # False(異なるオブジェクト)
# 同一オブジェクトの場合
c = a
print(a is c) # True(同一のオブジェクト)

実行結果はこちらです。

True False True

==は「中身が同じか」をチェックします。 isは「まったく同じオブジェクトか」をチェックするんです。

abは中身は同じだけど、別々に作られたリストなのでisではFalseになります。 でもc = aで同じオブジェクトを指しているので、a is cTrueです。

基本的な使い方

文字列と数値での確認

文字列と数値でis演算子を使ってみましょう。

# 文字列の場合
text1 = "Hello"
text2 = "Hello"
text3 = text1
print(f"text1 == text2: {text1 == text2}") # True
print(f"text1 is text2: {text1 is text2}") # True
print(f"text1 is text3: {text1 is text3}") # True
# 数値の場合
num1 = 100
num2 = 100
print(f"num1 is num2: {num1 is num2}") # True

実行結果はこちらです。

text1 == text2: True text1 is text2: True text1 is text3: True num1 is num2: True

あれ?text1text2は別々に作ったのにisでもTrueになってます。

実は、Pythonは効率化のために、小さな文字列や数値を同じオブジェクトとして扱うことがあるんです。

リストや辞書での確認

リストや辞書では、明確に違いが見えます。

# リストの場合
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1
print("=== リストの比較 ===")
print(f"list1 == list2: {list1 == list2}") # True(値が同じ)
print(f"list1 is list2: {list1 is list2}") # False(異なるオブジェクト)
print(f"list1 is list3: {list1 is list3}") # True(同一のオブジェクト)
# 辞書の場合
dict1 = {"name": "太郎", "age": 25}
dict2 = {"name": "太郎", "age": 25}
dict3 = dict1
print("
=== 辞書の比較 ===")
print(f"dict1 == dict2: {dict1 == dict2}") # True(値が同じ)
print(f"dict1 is dict2: {dict1 is dict2}") # False(異なるオブジェクト)
print(f"dict1 is dict3: {dict1 is dict3}") # True(同一のオブジェクト)

実行結果はこちらです。

=== リストの比較 === list1 == list2: True list1 is list2: False list1 is list3: True === 辞書の比較 === dict1 == dict2: True dict1 is dict2: False dict1 is dict3: True

リストや辞書は、中身が同じでも別々のオブジェクトとして作られます。

Noneとの比較方法

なぜNoneにはisを使う?

Noneとの比較では、必ずis演算子を使います。

# 正しいNone判定
value = None
if value is None:
print("値がNoneです")
# 非推奨(動作はするけど良くない)
if value == None:
print("値がNoneです")

Noneは特別なオブジェクトで、プログラム中に1つしか存在しません。 だからisを使うのが正しい方法なんです。

関数での活用例

関数でNoneチェックを使ってみましょう。

def get_user_data(user_id):
# データベースから検索(今回は例なのでNoneを返す)
if user_id == 999:
return {"name": "田中", "age": 30}
return None # データが見つからない場合
# 使ってみよう
user_data = get_user_data(123)
if user_data is None:
print("ユーザーデータが見つかりません")
else:
print(f"ユーザーデータ: {user_data}")
user_data = get_user_data(999)
if user_data is None:
print("ユーザーデータが見つかりません")
else:
print(f"ユーザーデータ: {user_data}")

実行結果はこちらです。

ユーザーデータが見つかりません ユーザーデータ: {'name': '田中', 'age': 30}

is None でデータが見つからない場合を判定できます。

is not演算子も便利

「Noneじゃない」ことを確認するにはis notを使います。

data = [1, 2, 3]
if data is not None:
print("データが存在します")
print(f"データの長さ: {len(data)}")
# 空のリストとNoneの区別
empty_list = []
if empty_list is not None:
print("リストは存在します(空かもしれません)")
if len(empty_list) == 0:
print("リストは空です")

実行結果はこちらです。

データが存在します データの長さ: 3 リストは存在します(空かもしれません) リストは空です

is not Noneで「Noneじゃない」ことを確認できます。

実践的な使い方

関数の初期値設定

関数でよく使われるパターンを見てみましょう。

def process_data(data, options=None):
if options is None:
options = {"format": "json", "encoding": "utf-8"}
print(f"データ: {data}")
print(f"オプション: {options}")
return f"処理完了: {data}"
# 使ってみよう
print("=== デフォルトオプション使用 ===")
process_data("Hello World")
print("
=== カスタムオプション使用 ===")
process_data("Hello World", {"format": "xml", "encoding": "shift-jis"})

実行結果はこちらです。

=== デフォルトオプション使用 === データ: Hello World オプション: {'format': 'json', 'encoding': 'utf-8'} === カスタムオプション使用 === データ: Hello World オプション: {'format': 'xml', 'encoding': 'shift-jis'}

if options is None でデフォルト値を設定できます。

データ処理クラスでの活用

クラスでの状態管理にも使えます。

class DataProcessor:
def __init__(self):
self.current_data = None
self.processed_data = None
def load_data(self, data):
self.current_data = data
self.processed_data = None # リセット
print(f"データをロードしました: {data}")
def process(self):
if self.current_data is None:
print("処理するデータがありません")
return
if self.processed_data is not None:
print("既に処理済みです")
return
# データ処理(各要素を2倍にする)
self.processed_data = [x * 2 for x in self.current_data]
print("データ処理完了")
def get_result(self):
if self.processed_data is None:
return "まだ処理されていません"
return self.processed_data
# 使ってみよう
processor = DataProcessor()
print("=== データ処理テスト ===")
processor.process() # データがない状態
processor.load_data([1, 2, 3, 4, 5])
processor.process()
print(f"結果: {processor.get_result()}")
processor.process() # 2回目の処理

実行結果はこちらです。

=== データ処理テスト === 処理するデータがありません データをロードしました: [1, 2, 3, 4, 5] データ処理完了 結果: [2, 4, 6, 8, 10] 既に処理済みです

is Noneis not None で処理状態を管理できます。

オブジェクトのIDを確認

id関数との関係

is演算子は内部的にオブジェクトのIDを比較しています。

# オブジェクトのIDを確認してみよう
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(f"a のID: {id(a)}")
print(f"b のID: {id(b)}")
print(f"c のID: {id(c)}")
print(f"
a is b: {a is b}") # False
print(f"a is c: {a is c}") # True
print(f"id(a) == id(c): {id(a) == id(c)}") # True

実行結果はこちらです(IDの値は実行ごとに変わります)。

a のID: 4373482624 b のID: 4373482704 c のID: 4373482624 a is b: False a is c: True id(a) == id(c): True

同じIDを持つオブジェクトは、同一のオブジェクトということです。

注意点と覚えておくこと

数値の特別な動作

小さな整数には特別なルールがあります。

# 小さな整数(-5から256)
a = 100
b = 100
print(f"a is b: {a is b}") # True
# 大きな整数
c = 1000
d = 1000
print(f"c is d: {c is d}") # 環境により異なる
# 計算結果
e = 50 + 50
f = 100
print(f"e is f: {e is f}") # True

実行結果はこちらです。

a is b: True c is d: False e is f: True

Pythonは効率化のために、よく使われる小さな整数を事前に作っておくんです。

浮動小数点数では使わない

浮動小数点数ではis演算子を使わないようにしましょう。

# 浮動小数点数の比較
float1 = 3.14
float2 = 3.14
print(f"float1 == float2: {float1 == float2}") # True
print(f"float1 is float2: {float1 is float2}") # False
# 計算結果の比較
result1 = 0.1 + 0.2
result2 = 0.3
print(f"result1 == result2: {result1 == result2}") # False
print(f"result1 is result2: {result1 is result2}") # False

実行結果はこちらです。

float1 == float2: True float1 is float2: False result1 == result2: False result1 is result2: False

浮動小数点数は複雑なので、値の比較には==を使いましょう。

実際の開発での使い方

設定管理システム

設定値の管理でis演算子を活用してみましょう。

class AppConfig:
def __init__(self):
self.debug_mode = None
self.log_level = None
self.max_users = None
def load_config(self, config_dict):
self.debug_mode = config_dict.get("debug", None)
self.log_level = config_dict.get("log_level", None)
self.max_users = config_dict.get("max_users", None)
def get_debug_mode(self):
if self.debug_mode is None:
return False # デフォルト値
return self.debug_mode
def get_log_level(self):
if self.log_level is None:
return "INFO" # デフォルト値
return self.log_level
def get_max_users(self):
if self.max_users is None:
return 100 # デフォルト値
return self.max_users
# 使ってみよう
config = AppConfig()
print("=== 設定なしの場合 ===")
print(f"デバッグモード: {config.get_debug_mode()}")
print(f"ログレベル: {config.get_log_level()}")
print(f"最大ユーザー数: {config.get_max_users()}")
print("
=== 設定ありの場合 ===")
config.load_config({
"debug": True,
"log_level": "DEBUG"
})
print(f"デバッグモード: {config.get_debug_mode()}")
print(f"ログレベル: {config.get_log_level()}")
print(f"最大ユーザー数: {config.get_max_users()}")

実行結果はこちらです。

=== 設定なしの場合 === デバッグモード: False ログレベル: INFO 最大ユーザー数: 100 === 設定ありの場合 === デバッグモード: True ログレベル: DEBUG 最大ユーザー数: 100

if self.debug_mode is None で未設定の項目をチェックできます。

まとめ

Python is演算子の基本から実践的な使い方まで解説しました。

今回学んだポイント

基本的な違い

  • ==演算子:値が同じかをチェック
  • is演算子:同じオブジェクトかをチェック
  • メモリ上の同じ場所を指しているかが重要

None判定

  • Noneとの比較には必ずisを使う
  • is not Noneで「Noneじゃない」をチェック
  • 関数の初期値設定でよく使われる

実践的な活用場面

  • 関数のデフォルト引数
  • データ処理の状態管理
  • 設定ファイルの管理
  • オブジェクトの同一性確認

注意点

  • 小さな整数や文字列は同一オブジェクトになることがある
  • 浮動小数点数ではisを使わない
  • リストや辞書は同じ内容でも別オブジェクト

is演算子を正しく使えるようになると、もっと正確で効率的なプログラムが書けます。 特にNone判定は頻繁に使うので、ぜひマスターしてくださいね!

関連記事