LoginSignup
0
0

More than 5 years have passed since last update.

Pythonのミュータブルなリスト

Posted at

はじめに

 先日、センター試験が終わりました。息抜きも兼ねての初投稿です。

 Pythonのリストはミュータブルなオブジェクトです。ただ、この特徴を活かせずにいました。そんな中でも使えそうな方法をいくつか紹介します。

ミュータブル、イミュータブルについて

pythonでは、
int, str, tuple ... -> イミュータブル
list, dict ... -> ミュータブル
なオブジェクトとなっています。
イミュータブルなオブジェクトは変更時にID(参照先)が変更されますが、ミュータブルなオブジェクトは変更されません。

>>> a = int(11)  #int型の変数
>>> id(a)
... 3077501696  #値の参照先
>>> b = a
>>> id(a) == id(b)
... True  #複製では変更されない。
>>> a = 7
>>> id(a)
... 3077501632  #IDが変わった
>>> c = list([1, 2, 3])  #list型の変数
... 2977380172
>>> c[0] = 10
>>> c.append(4)  #値の変更等
>>> id(c)
... 2977380172  #IDは変わらない

利用その1 参照渡しのように扱う

int型等と異なり、再代入をする必要がありません。

immutable1.py
def square(n):
    return pow(n, 2)

a = int(10)
a = square(a)
mutable1.py
def square(num_list):
    for i, num in enumerate(num_list):
        num_list[i] = pow(num, 2)

num_list = list(range(1, 6))  #-> [1, 2, 3, 4, 5]
square(num_list)
print(num_list)  #-> [1, 4, 9, 16, 25]

これは、リストのIDが値の変更時に変化しないからこそできるのです。

sample1.py
def square(num_list):
    print(id(num_list))  #-> 3037287628
    for i, num in enumerate(num_list):
        num_list[i] = pow(num, 2)
    print(id(num_list))  #-> 3037287628 変わらない

num_list = list(range(1, 6))  #-> [1, 2, 3, 4, 5]
print(id(num_list))  #-> 3037287628
square(num_list)
print(id(num_list))  #-> 3037287628 変わらない
print(num_list)  #-> [1, 4, 9, 16, 25]

ちなみに、num_list[i]はint型なので変更時にIDが変化します。

sample1.py
def square(num_list):
    print(id(num_list[0]))  #-> 3078230624 変わらない  
    for i, num in enumerate(num_list):
        num_list[i] = pow(num, 2)
    print(id(num_list[0]))  #-> 3078232576 変わる

num_list = list(range(1, 6))  #-> [1, 2, 3, 4, 5]
print(id(num_list[0]))  #-> 3078230624
square(num_list)
print(num_list)  #-> [1, 4, 9, 16, 25]

利用その2 要素数を増やしながらループさせる

for i in 配列:に対して用います。

immutable2.py
seq = tuple([1])  # type -> tuple
for i in seq:
    if i > 5:  break
    seq += (i+1,)
    print(i)  #-> 1
mutable2.py
seq = [1]  # type -> list
for i in seq:
    if i > 5:  break
    seq.append(i+1)
    print(i)  #-> 1 2 3 4 5

可読性等の面で実用的とは言えませんが、フィボナッチ数列等を完結に表現できます。

fib.py
def fib1(n):
    seq = [0, 1]
    if n <= 2:  return seq[0:n]
    for i in range(n-2):
        seq.append(seq[i]+seq[i+1])
    return seq

def fib2(n):
    return [(seq.append(seq[i]+seq[i+1]), seq[i])[1] for seq in [[0, 1]] for i in range(n)]

おわりに

他にも面白い使い方を探して行きたいと思います。(受験後に)
まだ初心者なので間違いもあるかもしれません。もし解釈の間違いや実際にあった難解な使い方がありましたら、訂正等のコメントをよろしくお願いします。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0