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

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

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

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

Q&A

解決済

1回答

2778閲覧

動的に変動する二次元配列に対してzipをかけたい

mofu_mofu

総合スコア73

Python 3.x

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

0グッド

0クリップ

投稿2018/03/04 12:33

編集2018/03/04 13:40

いつもお世話になっております。

このyukicoderの問題を解いていて、
例えばN行*N列の行列のinput()が下記のように入力され、

4 - hoge fuga mogu fuga - mofu piyo piyo hoge mogu mofu hoge hoge - piyo

の多次元配列であれば[N][1]のすべてをzip()でまとめて("-","hoge","hoge","hoge")としたいです。(tupleの順番は問わず,"-"とハイフン以外すべて"hoge"の配列がほしい)
そうすれば解きやすいのかな?と考えています。

この場合であれば

>>>la =['-', 'hoge', 'fuga', 'mogu'] >>>lb = ['fuga', '-', 'mofu', 'piyo'] >>>lc = ['piyo', 'hoge', 'mogu', 'mofu'] >>>ld = ['hoge', 'hoge', '-', 'piyo'] >>>print(list(zip(la,lb,lc))) [('-', 'fuga', 'piyo', 'hoge'), ('hoge', '-', 'hoge', 'hoge'), ('fuga', 'mofu', 'mogu', '-'), ('mogu', 'piyo', 'mofu', 'piyo')] >>>print(list(zip(la,lb,lc,ld))[1]) ('hoge', '-', 'hoge', 'hoge')

こんなかんじに。

しかし、この問題で与えられるNが2≤N≤100を取り、一次元配列と二次元配列の個数がNにより動的に決まるので、la,lbなどの変数に値を格納できないです。なのでもう少しひねる必要が出てきます。

変数に格納せずに、動的に変動する二次元配列に対してzip()をかけたいのですが何がいい方法はありますでしょうか。

よろしくお願いいたします。

###いただいた回答を受けて

書いたコード

n = int(input()) greet = [input().split() for i in range(n)] sorted_greet = [] for i in range(n): greet_in_row = [row[i] for row in greet] sorted_greet.append(greet_in_row) print(sorted_greet)

入力

- nyanpass uissu ohayo konbanwa - ohayo ohayo ohayogozaimasu nyanpass - komachanyuuna konnichiwa nyanpass komachanohayo -

出力

[['-', 'konbanwa', 'ohayogozaimasu', 'konnichiwa'], ['nyanpass', '-', 'nyanpass', 'nyanpass'], ['uissu', 'ohayo', '-', 'komachanohayo'], ['ohayo', 'ohayo', 'komachanyuuna', '-']]

#解決策

このような回答でACになりました。LouiS0616さんありがとうございました。

n = int(input()) greet = [input().split() for i in range(n)] sorted_table = [] for i in range(n): greet_in_row = [row[i] for row in greet] sorted_table.append(greet_in_row) nyanpass_cnt = [] for i in range(len(sorted_table)): l = sorted_table[i] l.remove("-") sl = set(l) if (len(sl) == 1) and (sl) == {"nyanpass"}: nyanpass_cnt.append(True) else: nyanpass_cnt.append(False) if True in nyanpass_cnt: if nyanpass_cnt.count(True) == 1: print(nyanpass_cnt.index(True) + 1) else: print(-1) else: print(-1)

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

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

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

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

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

guest

回答1

0

ベストアンサー

『リストのリスト』にすればいいと思いますよ。

Python

1list_list = [ 2 ['-', 'hoge', 'fuga', 'mogu'], 3 ['fuga', '-', 'mofu', 'piyo'], 4 ['piyo', 'hoge', 'mogu', 'mofu'], 5 ['hoge', 'hoge', '-', 'piyo'] 6] 7print([row[1] for row in list_list]) # ['hoge', '-', 'hoge', 'hoge']

書いてみた

書いてみました。競プロっぽくないコードではありますが、参考までに。

Python

1def get_col(mat, col_num): 2 return [row[col_num] for row in mat] 3 4def col_enumerate(mat, start=0): 5 for col_num, _ in enumerate(mat[0]): 6 yield start, get_col(mat, col_num) 7 start += 1 8 9N = int(input()) 10 11greeting_table = [ 12 input().split() for _ in range(N) 13] 14renchons = [ 15 i for i, greets in col_enumerate(greeting_table, start=1) 16 if all(elem in ('nyanpass', '-') for elem in greets) 17] 18 19print( 20 renchons[0] if len(renchons) == 1 else -1 21)

転置バージョン。こっちの方がよさそう。

Python

1def enumerate_col(mat, start=0): 2 return enumerate(zip(*mat), start=start) 3 4N = int(input()) 5 6greeting_table = [ 7 input().split() for _ in range(N) 8] 9renchons = [ 10 i for i, greets in enumerate_col(greeting_table, start=1) 11 if all(elem in ('nyanpass', '-') for elem in greets) 12] 13 14print( 15 renchons[0] if len(renchons) == 1 else -1 16)

投稿2018/03/04 12:44

編集2018/03/04 13:41
LouiS0616

総合スコア35660

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

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

mofu_mofu

2018/03/04 13:06

LouiS0616さん 大変お世話になっております。 もともとリストで作成していたのですがうまくいかず、そういえばzipでまとめられるなあと思い迷走をしておりました。解決いたしました。ありがとうございます。 ちなみになのですが、修正したコードを載せたのですが、このfor文を内包表記で書くのであればどのようなコードになるのでしょうか? [(row,col) for row in rows for col in cols]のように多重ループを書けるのは知っているのですが、使いこなせておらず...。 以上になりますがどうぞよろしくお願いします。
LouiS0616

2018/03/04 13:08

sorted_greet = [[row[i] for row in greet] for i in range(n)] ですかね。 ただsorted_greetという変数名はちょっと違和感があります。
LouiS0616

2018/03/04 13:09

あ、ひょっとしたら二次元リストをごっそり転置した方が分かりやすいかも。
mofu_mofu

2018/03/04 13:21 編集

LouiS0616さん sorted_greetの件、ありがとうございます。 LouiS0616さんの問題に対する回答がコーディングスピードが桁違いすぎてちょっと理解が追いついていません。。一度書いてACを出してから再度確認をさせていただきます。
mofu_mofu

2018/03/04 14:16

転置の方を読ませていただきました。 ループを回したいけどインデックスとして使わないときはfor i in list:ではなくfor _ in list:のように使われていたり?zip(*greeting_table)のように多重配列をzipの可変長引数として与えることができたり? 内包表記のifは改行しても認識されたりするのですね。大変勉強になりました。 ちなみにこのif内のall()の詳しい挙動が追えませんでした。 all()は文字列の配列であれば空文字以外でTrueを返すと認識していますが、zipしたものの各要素をallしている意図ってなんでしょうか? if all(elem in ('nyanpass', '-') for elem in greets) よろしくお願いいたします。
LouiS0616

2018/03/04 14:36 編集

allはiterableオブジェクトを受け取り、全ての要素が真であるときにTrueを、そうでないときにFalseをかえします。 allを自前で実装すると、こんな感じになります。 def my_all(iterable): ....for elem in iterable: ........if not elem: ............return False ....return True 註:空白をドットで代替しています。
LouiS0616

2018/03/04 14:28

今回allに渡した引数は、(elem in ('nyanpass', '-') for elem in greets)ですね。 これはジェネレータ内包表記ですが、慣れるまではリスト内包に読み替えると良いでしょう。 つまり、[elem in ('nyanpass', '-') for elem in greets]ですね。 これは、『全ての要素について、elem in ('nyanpass', '-')の結果をリストにしたもの』です。
LouiS0616

2018/03/04 14:30

さて、elem in ('nyanpass', '-')とは何か。 これは『elemが'nyanpass'あるいは'-'』と解釈します。
LouiS0616

2018/03/04 14:40

まとめると、次のような感じでしょうか。 enumerate_col(greeting_table, start=1)の結果を巡回し、新たなリストrenchonsを作る。ただし、リストに含めるのは all(elem in ('nyanpass', '-') for elem in greets) が真である要素のみ。この条件は、『greetsの全ての要素が'nyanpass'あるいは'-'である』ことを意味する。
mofu_mofu

2018/03/04 15:18

LouiS0616さん all()内のジェネレーター内包表記内で各要素がnyanpass'か'-'を判定してTrueかFalseを結果として返す ↓ その結果をリスト(ここではgeneratorですが)にまとめる ↓ そのリストの中がすべてTrueであればall()はTrueを返し、そうでなければall()はFalseを返す ↓ それがrenchonsのリスト内包表記の条件文になる ということなのですね。理解いたしました。 長々とありがとうございました。深く感謝いたします。
LouiS0616

2018/03/04 16:31

拙い説明ではありましたが、ご理解頂けたようで何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問