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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

273閲覧

配列の要素をスライスさせ、0番目の要素で処理を変えたい

退会済みユーザー

退会済みユーザー

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/07/31 05:47

編集2017/07/31 06:29

二次元配列でその要素があればすでにある配列に数字を格納したいです。

X = [[0, 3, 7], [0, 9, 8], [1, 1, 6], [1, 8, 3], [0, 5, 9], [1, 1, 5], [0, 8, 3], [1, 8, 2]]

という配列Xがあります。この配列を別の配列Yに入れ替えたいです。入れ替える条件指定として、
二次元配列で既出の数字が入っている配列があれば、その配列に数字を格納したいです。つまり、0番目の要素が0のもの([0, 3, 7], [0, 9, 8],[0, 5, 9],[0, 8, 3])を別の配列Yにいれたいということです。また、0番目の要素が1のものの時はそれぞれhelloと出力させたいです。

X = [[0, 3, 7], [0, 9, 8], [1, 1, 6], [1, 8, 3], [0, 5, 9], [1, 1, 5], [0, 8, 3], [1, 8, 2]] for i in range(8): if X[i][0] == 0: temp = [ set( X[0][1:3] ) ] print(temp) for x in X[i][1:3]: xSet = X[i][1:3] for y in temp: if not y.isdisjoint(xSet): y |= xSet break else: temp.append( xSet ) else: print("hello") Y = [ list(x) for x in temp ] print(Y)

とコードを書きましたが、

y |= xSet TypeError: unsupported operand type(s) for |=: 'set' and 'list'

とエラーが出ました。理想のアウトプットは、print(Y)で

[[3,7,9,8,5]]

と出力されることです。
どのように直せば目的のアウトプットになりますか?
ちなみに、もし配列Xが

X = [[0, 3, 7], [0, 9, 8], [1, 1, 6], [1, 8, 3], [0, 5, 9], [1, 1, 5], [0, 8, 3], [1, 8, 2],[0, 2, 4]]

なら理想のアウトプットは

[[3,7,9,8,5],[2,4]]

です。

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

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

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

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

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

Lhankor_Mhy

2017/07/31 06:03

「理想のアウトプット」はそれで合っていますか?
退会済みユーザー

退会済みユーザー

2017/07/31 06:27

すみません、間違っていました。この場合、[[3,7,9,8,5]]です。
Lhankor_Mhy

2017/07/31 07:26

そうはならないような……? 0番目の要素が[3,7]で1番目の要素が[9,8]だと思いますが、一緒の配列にまとめる方法でいいんでしょうか。
退会済みユーザー

退会済みユーザー

2017/07/31 07:49

0番目の要素の意味は、[0, 3, 7]の0、[0, 9, 8]の0、[1, 1, 6]の1、[1, 8, 3]の1、[0, 5, 9]の0・・・を指しています。この0番目の要素が0なら一緒の配列にまとめたいという意味です。
Lhankor_Mhy

2017/07/31 07:57

とすると、ふたつめのアウトプットがよく分からないんですが…… [0, 2, 4]も0番目の要素が0では?
退会済みユーザー

退会済みユーザー

2017/07/31 08:23

2つの要素([3, 7]、[9, 8]、[5, 9]など)のどちらかがもうすでに配列に入っていればすでにある配列に数字を格納したいからです。
退会済みユーザー

退会済みユーザー

2017/07/31 08:24

[2, 4]のどちらも[[3,7,9,8,5]]には存在していないから、[2, 4]は別の配列に存在することになります。
Lhankor_Mhy

2017/07/31 08:27

ですよね。そうすると[3, 7]と[9, 8]は別れると思うんですが。
退会済みユーザー

退会済みユーザー

2017/07/31 08:39

[0, 8, 3]があるから、[3, 7]と[9, 8]は一緒になります。途中まではYは別々の配列だったのが、[0, 8, 3]が出てきたときに[3, 7]と[9, 8]は一緒の配列に入ります。
Lhankor_Mhy

2017/07/31 08:47

それは質問文に明記しておいた方がいいのでは……
guest

回答1

0

ベストアンサー

順序が変わってもいいのならこれでできそうです.

python

1X = [[0, 3, 7], [0, 9, 8], [1, 1, 6], [1, 8, 3], [0, 5, 9], [1, 1, 5], [0, 8, 3], [1, 8, 2]] 2# X = [[0, 3, 7], [0, 9, 8], [1, 1, 6], [1, 8, 3], [0, 5, 9], [1, 1, 5], [0, 8, 3], [1, 8, 2],[0, 2, 4]] 3Y = [] 4 5for x in X: 6 if x[0] == 0: 7 Y.append(set(x[1:])) 8 else: 9 print("hello") 10 11for i in range(len(Y) - 1): 12 for j in range(i + 1, len(Y)): 13 if not Y[i].isdisjoint(Y[j]): 14 Y[j] |= Y[i] 15 Y[i].clear() 16 break 17 18Y = list(filter(lambda x: len(x) > 0, [list(y) for y in Y])) 19print(Y) 20# [[3, 5, 7, 8, 9]] 21# or 22# [[3, 5, 7, 8, 9], [2, 4]]

エラーの原因は xSetset ではないからなので,xSet = set(X[i][1:3]) とすればエラーは消えます.
しかし,今のコードではtemp が毎回初期化されるので,エラーが消えてもアウトプット(Y)は

[[8, 3, 7]]

です.
また,今の方針だと,一度違うグループだと判定されたものが後から同じグループに属するようになった場合には対処できません.

なので,いったん 要素の0番目が0のものをすべて取り出しておいて,あとからもう一度ループを回して処理するという方針にしました.


Yの各要素について,自分以外の要素と共通な数値を持つかどうか,というのを判定します.

判定はY[0]から,Y[0] - Y[1], Y[0] - Y[1], ..., Y[0] - Y[n-1] としていきます(nlen(Y)).
共通だと判定された時点で,Y[0] を 共通なグループに合併して,判定をやめて次(Y[1])に移ります.
これを Y[n-1] まで行います

Y[0]について判定が終わった時点で,Y[0] に含まれていた数値は,

  1. Y[1] .. Y[n] に含まれている
  2. Y[1] .. Y[n] に含まれいない

のどちらかですが,いずれの場合もこれ以降Y[0]についての判定は必要ありません.

なので,内側のループは i+1からになっています.

合併後にY[i].clear() としているのは,後で削除しやすいように空のの set にしています.Y[i] = set() と同じです.

投稿2017/07/31 10:32

編集2017/07/31 13:18
what_alnk

総合スコア147

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

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

退会済みユーザー

退会済みユーザー

2017/07/31 12:25

ありがとうございます。2点質問があります。 1点目は、 if x[0] == 0: Y.append(set(x[1:])) の部分でなぜsetを使っているのでしょうか? 2点目は、 for i in range(len(Y) - 1): for j in range(i + 1, len(Y)): if not Y[i].isdisjoint(Y[j]): Y[j] |= Y[i] Y[i].clear() break の 部分はどのような処理をやっているのでしょうか?
what_alnk

2017/07/31 13:14

1点目ですが,グループの判定をsetでするという方針にしたので,判定が終わるまではset で保存しておいて最後にlistに変換する,というふうにしました.もちろん,list で保存しておいて 毎回 Y から取り出すときに set にして グループを更新してからlist にまた戻す,ということもできますが. 2点目は回答の方に追記します.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問