SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Pythonの新機能を知ろう!

Python 3.15の新機能――明示的な遅延インポートとイミュータブルな辞書型などを解説

Pythonの新機能を知ろう! 第8回

WINGSプロジェクト 山内 直[著] / 山田 祥寛[監修]

省略や無効を明確に示す! 番兵値を明確に表すsentinel型で曖昧さを排除

 関数の引数が省略されたことや、戻り値が特別な状態を示すことを表すために、番兵値(センチネル)を使うことがあります。

 たとえばNoneを使って引数の省略を表す方法がありますが、呼び出し側がNone自体を値として渡したい場合には、省略された場合と区別できません。

 Python 3.15では、組み込みのsentinelを使って、一意の番兵値を簡潔に作成できるようになりました。これにより、Noneなどの通常の値とは区別できる目印を用意できます。

 以下のリストは、sentinelの基本的な使い方を示したものです。

リスト sentinel.py
OMITTED = sentinel("OMITTED")			(1)

def describe_name(name=OMITTED):		(2)
    if name is OMITTED:				(3)
        return "名前は指定されていません"
    if name is None:				(4)
        return "名前にNoneが指定されました"
    return f"名前: {name}"

print(describe_name())			# 名前は指定されていません
print(describe_name(None))		# 名前にNoneが指定されました
print(describe_name("やまだ"))		# 名前: やまだ

 このコードでは、引数が省略された場合と、Noneが明示的に渡された場合を区別しています。

 (1)では一意の番兵値を作成し、変数OMITTEDに代入しています。この値を表示すると、既定ではOMITTEDと表示されます。

 (2)では、引数nameのデフォルト値にOMITTEDを指定しています。引数を省略すると、この番兵値が使われます。(3)では、is 演算子で引数が番兵値と同一かどうかを判定しています。sentinelで作成した値は、それ自体との同一性をisで判定するのが基本です。

 一方、(4)の「name is None」は、引数にNoneが渡されたかどうかを判定します。このように番兵値を利用すれば、引数の省略と、Noneを値として指定することを明確に区別できます。

内包表記におけるアンパッキング

 Python 3.15では、リスト、セット、辞書の内包表記とジェネレータ式で、*や**を使ったアンパック構文を利用できるようになりました。これにより、複数の反復可能オブジェクトや辞書の内容を、簡潔な構文で1つにまとめられます。

 まず、内包表記の基本を確認しましょう。内包表記は、反復処理などを使ってリストやセット、辞書を簡潔に作成するための構文です。次の例では、range(10)から偶数を取り出し、それぞれの自乗を計算したリストを作成しています。

リスト comprehension.py
squares = [number * number for number in range(10) if number % 2 == 0]
print(squares)		# [0, 4, 16, 36, 64]

 一方、ジェネレータ式は、値を一度にすべて生成するのではなく、必要に応じて順番に取り出せるオブジェクトを作成する構文です。リスト内包表記と似ていますが、角かっこ[]の代わりに丸かっこ()を使います。得られるのはイテラブルオブジェクトなので、以下のリストのようにnextやlistを使って値を取り出します。

リスト generator.py
squares = (number * number for number in range(10) if number % 2 == 0)
print(next(squares))	# 0
print(next(squares))	# 4
print(list(squares))	# [16, 36, 64]

 なお、yieldを使って定義するジェネレータ関数も、値を順番に生成する仕組みですが、ジェネレータ式とは別の構文です。ジェネレータ式では複雑になるような処理を表現するのに向いています。

リスト generator.py
def calc_square(limit):
    for number in range(limit):
        if number % 2 == 0:
            yield number * number

for value in calc_square(10):
    print(value, end=" ")
print()					# 0 4 16 36 64 

 Python 3.15の新しいアンパック構文を使うと、内包表記の各反復で得られた反復可能オブジェクトの要素を、*で展開してまとめられます。また、辞書の内包表記では、**を使って辞書のキーと値の組を展開できます。ジェネレータ式でも、*による展開を利用できます。

 以下のリストで、それぞれの使い方を確認しましょう。

リスト unpack.py
lists = [[1, 2], [3, 4], [5]]

# リストのリストを平坦化する
flat = [*items for items in lists]
print(flat)				# [1, 2, 3, 4, 5]

# 辞書からは**を使って取り出す
dicts = [{"a": 1}, {"b": 2}, {"a": 3}]
combined = {**item for item in dicts}
print(combined)				# {'a': 3, 'b': 2}

# ジェネレータ式
generator = (*items for items in lists)
print(next(generator))			# 1
print(next(generator))			# 2
print(list(generator))			# [3, 4, 5]

 最初の例では、各リストの要素を*で展開し、1つのリストにまとめています。従来の内包表記であれば、[item for items in lists for item in items]と書く処理に相当します。

 2番目の例では、各辞書のキーと値の組を**で展開し、1つの辞書にまとめています。同じキーが複数回現れた場合は、後から展開された値が採用されます。この例では、キーaの値が3になります。

 最後の例では、ジェネレータ式によって、各リストの要素を順番に生成するジェネレータを作成しています。nextを呼び出すたびに次の要素が得られ、残りの要素はlistでまとめて取り出せます。

 このように、Python 3.15のアンパック構文を使うと、複数のリストや辞書をまとめる処理を、従来より簡潔に記述できます。

次のページ
型付き追加項目を持つ型付き辞書

この記事は参考になりましたか?

Pythonの新機能を知ろう!連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー