Pythonのa += bは必ずしもa = a + bと同じではない
Pythonにおいて、2つの変数が同じデータ型であり、リストや辞書のようなイテラブル(反復可能オブジェクト)でない場合、a += bとa = 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 += bとa = a + bはほぼ同じ結果になります。しかし、リストのようなミュータブルなイテラブルを扱う際には、両者の挙動が大きく異なる場合があるため注意が必要です。意図しない要素の展開を防ぐためにも、それぞれの演算子の内部的な動作を理解しておくことが重要です。
-
【Python】リストが最大ヒープを形成しているかどうかを判定する方法
リストがヒープツリー(完全二分木)を表していると仮定します。このとき、その要素が最大ヒープ(max heap)を形成しているかどうかを判定する必要があります。 最大ヒープとは、すべての親ノードがその左右の子ノードのどちらよりも大きい(または等しい)という性質を持つヒープのことです。 たとえば、入力が nums = [8, 6, 4, 2, 0, 3] の場合、出力は True になります。これは、すべての親要素がそれぞれの子要素より大きいためです。 解決手順 この問題は、次の手順で解決できます。 n := nums のサイズとする i を 0 から n - 1 までループする m :=
-
Pythonで数値が二面素数(Dihedral Prime)かどうかを判定する方法
ある整数nが与えられたとき、それが「二面素数(dihedral prime)」であるかどうかを判定する方法を解説します。二面素数とは、その数自体が素数であり、さらに7セグメントディスプレイに表示した際に、表示の向き(通常の向きでも上下逆さまでも)に関わらず、同じ数または別の素数として読み取れる数のことです。例えば、入力がn = 1181の場合、出力はTrueになります。下の数字は上の数字を上下逆さま(180度回転)にして表示したものであり、どちらも素数となっています。アルゴリズムの手順この問題を解くために、以下の手順で進めます。up_side_down() 関数を定義します。引数としてnを受け