Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonのa += bは必ずしもa = a + bと同じではない

Pythonにおいて、2つの変数が同じデータ型であり、リストや辞書のようなイテラブル(反復可能オブジェクト)でない場合、a += ba = a + bは同じ結果をもたらします。しかし、イテラブルなオブジェクトが関わってくると、必ずしも同じ結果になるとは限りません。本記事では、その典型的なシナリオを具体例とともに紹介します。

a = a + b のケース

まず、リストと文字列を結合しようとしてa = a + bという式を適用した場合を見てみましょう。この場合、エラーが発生します。

x = 'Hello '
z_list = [1, 2, 3]
z_list = z_list + x
print(z_list)

出力

上記のコードを実行すると、次の結果が得られます。

Traceback (most recent call last):
    File "C:\Users\Pradeep\AppData\Roaming\JetBrains\PyCharmCE2020.3\scratches\scratch.py", line 11, in
        z_list = z_list + x
TypeError: can only concatenate list (not "str") to list

+演算子によるリストの連結では、異なる型(この場合は文字列)を直接結合することができず、TypeErrorが発生します。

a += b のケース

一方、a += bという式を適用すると、文字列が暗黙的に個々の要素へと分解され、リストの一部として追加されることがわかります。

z_list = [1, 2, 3]
x = 'Hello'
z_list += x
print(z_list)

出力

上記のコードを実行すると、次の結果が得られます。

[1, 2, 3, 'H', 'e', 'l', 'l', 'o']

なぜこのような違いが生じるのか

この挙動の違いは、+=演算子(インプレース加算)が内部で__iadd__メソッドを呼び出すのに対し、+演算子は__add__メソッドを呼び出すことに起因します。ミュータブル(可変)なオブジェクトであるリストの場合、__iadd__extend()と同等の動作をするため、イテラブルなオブジェクト(文字列など)の各要素が個別にリストへ追加されます。つまり、z_list += xは実質的にz_list.extend(x)と同じ意味を持つのです。

まとめ

イミュータブル(不変)なオブジェクトや単純な数値同士の演算では、a += ba = a + bはほぼ同じ結果になります。しかし、リストのようなミュータブルなイテラブルを扱う際には、両者の挙動が大きく異なる場合があるため注意が必要です。意図しない要素の展開を防ぐためにも、それぞれの演算子の内部的な動作を理解しておくことが重要です。

  1. 【Python】リストが最大ヒープを形成しているかどうかを判定する方法

    リストがヒープツリー(完全二分木)を表していると仮定します。このとき、その要素が最大ヒープ(max heap)を形成しているかどうかを判定する必要があります。 最大ヒープとは、すべての親ノードがその左右の子ノードのどちらよりも大きい(または等しい)という性質を持つヒープのことです。 たとえば、入力が nums = [8, 6, 4, 2, 0, 3] の場合、出力は True になります。これは、すべての親要素がそれぞれの子要素より大きいためです。 解決手順 この問題は、次の手順で解決できます。 n := nums のサイズとする i を 0 から n - 1 までループする m :=

  2. Pythonで数値が二面素数(Dihedral Prime)かどうかを判定する方法

    ある整数nが与えられたとき、それが「二面素数(dihedral prime)」であるかどうかを判定する方法を解説します。二面素数とは、その数自体が素数であり、さらに7セグメントディスプレイに表示した際に、表示の向き(通常の向きでも上下逆さまでも)に関わらず、同じ数または別の素数として読み取れる数のことです。例えば、入力がn = 1181の場合、出力はTrueになります。下の数字は上の数字を上下逆さま(180度回転)にして表示したものであり、どちらも素数となっています。アルゴリズムの手順この問題を解くために、以下の手順で進めます。up_side_down() 関数を定義します。引数としてnを受け