somolyot
@somolyot (somolyot)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Python】setのlist、[set(), set()] と [set()] * 2 の違い

Q&A

Closed

基本的なことで申し訳ないのですが、ご存知の方がいたら簡単に教えていただけるとありがたいです。

知りたいことは表題の通りなのですが、例えば以下の上段と下段は同じ結果が得られると思っていたのですが、

Sample
b = [set()] * 5
print(b)
b[1].add(1)
b[2].add(2)
print(b, b[0], b[1], b[2], b[3], b[4])

d = [set(), set(), set(), set(), set()]
print(b)
d[1].add(1)
d[2].add(2)
print(d, d[0], d[1], d[2], d[3], d[4])

以下のように違う結果となります。(期待していたのは下段)

output
[set(), set(), set(), set(), set()]
[{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}] {1, 2} {1, 2} {1, 2} {1, 2} {1, 2}

[set(), set(), set(), set(), set()]
[set(), {1}, {2}, set(), set()] set() {1} {2} set() set()

list内のsetの個数があらかじめ決まっていて、しかも数個だったら下段のように対応すればいいのかもしれませんが、setの個数が多かったり後からset個数が変わるようなときは下段のようには対応できないので、どうしたものかと思っています。

お知恵を貸してください。

0

1Answer

リテラルはミュータブルなオブジェクトなので、それほど難しくないと思います。

まず、 *で作った場合インスタンスを生成するわけでなく、参照を渡しているだけということを確認するには、次のようにすれば良いです。

d = [set()] * 6
id(d[0]) == id(d[1]) # => True

数が多い場合

d = [ set() for _ in range(100)]
d[1].add(1)
d[2].add(2)
d

あとから追加。

d = []
d.append(set())
d.append(set())
d.append(set())
d[1].add(1)
d[2].add(2)
d

ループの中でappendを使って多数を一度に追加することもできます。

2Like

Comments

  1. @somolyot

    Questioner

    ありがとうございます。助かりました。
    「あ、そっか。」となりますけど、自分一人だと浅い沼なのに溺れかけることがありますね。(笑)
    いつもリスト内のリストとかセットの扱いで戸惑ってしまいます。

Your answer might help someone💌