質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

3493閲覧

冪集合の作成(Python3)

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/03/23 05:58

リストを受け取り、冪集合を出力する関数を作成したのですが、期待する出力結果を得られません。
コードは以下の通りです。

python

1def power_set(item_lists): 2 3 p_sets = [[]] 4 5 for item in item_lists: 6 new_p_sets = p_sets.copy() 7 for element in new_p_sets: 8 element.append(item) 9 p_sets = p_sets + new_p_sets 10 11 return p_sets

例をあげると、power_set([1,2,3])を実行すれば

[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

が出力されるはずなのですが、出力された結果は

[[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3],
[1, 2, 2, 3, 3, 3, 3]]

でした。コードの間違っている点を指摘していただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

外側のリストはコピーされるかもしれませんが、内側のelementは最初に書いた1つしかないままなので、そうなります。

こんな感じで書くと良いんじゃないでしょうか。

python

1def power_set(item_lists): 2 3 p_sets = [[]] 4 5 for item in item_lists: 6 tmp = [] 7 for element in p_sets: 8 tmp.append(element + [item]) 9 p_sets.extend(tmp) 10 11 return p_sets 12print(power_set([1,2,3])) 13# => [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

投稿2019/03/23 06:17

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/23 07:35

すみません、"内側のelementは最初に書いた1つしかないまま" とはどういうことでしょうか?
hayataka2049

2019/03/23 07:52

p_sets.copy()でcopyされるのは外側のlistだけで、内側の[]は参照がコピーされるだけです。 for element in new_p_sets: element.append(item) p_sets = p_sets + new_p_sets elementは常に同じものを参照しているので、1が1回、2が2回、3が3回というlistになります(結果の子リストも言うまでもないですがすべて同じlistへの参照です)
退会済みユーザー

退会済みユーザー

2019/03/23 10:51

理解できました!ありがとうございます!!
guest

0

全ての組み合わせを返すイテレータcombinationsを使ったジェネレータとしてこうも書けるのかな。

python

1from itertools import combinations 2 3def power_set(items): 4 n = len(items) 5 for i in range(n+1): 6 yield from combinations(items, i) 7 8print(list(power_set([1,2,3])))

投稿2019/03/23 06:49

tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/23 07:36

ありがとうございます!
guest

0

y.py

python3

1p_sets = [] 2 3n = 3 4for i in range(2 ** n): 5 lst = [x + 1 for x in range(i) if 2 **x & i] 6 p_sets.append(lst) 7 8 9print(sorted(p_sets, key=lambda x: len(x)))

実行例
イメージ説明

求める集合の要素の数は 2 ** n です。
数字 0 から 2 ** n - 1 に対応する要素を次のようにして求めます。

  • 数字を 2 進数で表したときの 1, 0 が、要素に含まれている/いない

投稿2019/03/23 09:19

編集2019/03/23 14:21
katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/23 10:54

なるほど、ビット演算を使うとだいぶスッキリと書けますね。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問