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

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

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

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Python

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

Q&A

解決済

3回答

2239閲覧

Pythonで二重ループが二重ループにならない

katak

総合スコア9

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Python

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

0グッド

0クリップ

投稿2020/05/21 06:17

前提・実現したいこと

以下のようなファイル(タブ区切りテキスト)があります。

int

1scaffold_1 537 1133 jg14231 0 + 2scaffold_1 1195 4118 jg14231 0 + 3scaffold_1 4229 7986 jg14231 0 + 4scaffold_1 8047 10192 jg14231 0 + 5scaffold_1 10355 12044 jg14231 0 + 6scaffold_1 20418 24388 jg14232 0 + 7scaffold_1 24653 25262 jg14232 0 + 8scaffold_1 25374 27128 jg14232 0 + 9scaffold_1 27274 31663 jg14232 0 + 10scaffold_1 31782 37803 jg14232 0 + 11(以下省略 合計94,052行)

rep

1scaffold_1 2582 2610 Simple_repeat 0 + 2scaffold_1 2725 3086 DNA/hAT-Charlie 0 + 3scaffold_1 3191 3410 Unknown 0 - 4scaffold_1 3414 4085 Unknown 0 - 5scaffold_1 4294 4454 Unknown 0 - 6scaffold_1 4465 4729 SINE/tRNA 0 + 7scaffold_1 4736 5063 Unknown 0 + 8scaffold_1 5332 5380 Low_complexity 0 + 9scaffold_1 6155 6338 Unknown 0 - 10scaffold_1 6419 6914 DNA/TcMar-Mariner 0 - 11(以下省略 合計3,965,884行)

これら2つのそれぞれのファイルの各行を総当たりで比較したいです。
すなわち、

intの1行目 vs. repの1行目
intの1行目 vs. repの2行目
intの1行目 vs. repの3行目
・・・・中略
intの94,052行目 vs. repの3,965,882行目
intの94,052行目 vs. repの3,965,883行目
intの94,052行目 vs. repの3,965,884行目

といった具合です。

発生している問題・エラーメッセージ

forを用いた多重ループで解決できると思いましたが、何故か最初のfor文がループされません。
すなわち、

intの1行目 vs. repの1行目
intの1行目 vs. repの2行目
intの1行目 vs. repの3行目
・・・・中略
intの1行目 vs. repの3,965,883行目
intの1行目 vs. repの3,965,884行目

で止まってしまいます。

該当のソースコード

python3

1with open(intron, 'r') as i, open(rep, 'r') as r: 2 reader_int = csv.reader(i, delimiter='\t') 3 reader_rep = csv.reader(r, delimiter='\t') 4 5 for line_int in reader_int: 6 for line_rep in reader_rep: 7 ### 処理内容

これを実行してwc -l しても3,965,884しか返ってきません。
ご教授いただけますと幸いです。

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

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

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

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

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

guest

回答3

0

csv.readerはイテレータなので、一回読んだら終わりです。

tachikomaさんの回答の方法でもできると思いますが、どう考えても遅いのでメモリに展開できないか考えてみます。問題は大きい方のrepの方がどれくらいの大きさになるかですが、一行メモリに乗せるのに必要なサイズを調べてみると、

python

1>>> s = "scaffold_1 2582 2610 Simple_repeat 0 +" 2>>> l = s.split() 3>>> l 4['scaffold_1', '2582', '2610', 'Simple_repeat', '0', '+'] 5>>> import sys 6>>> sys.getsizeof(l) + sum(sys.getsizeof(x) for x in l) 7487

一行で500バイト弱食います。あと念の為に考えておかないといけないのは、リストとして持たせるなら外側のリストの分もあるので、

python

1>>> sys.getsizeof([None]*1000) 28064 3>>> sys.getsizeof([None]*10000) 480064

で一行持たせるのに8バイト食うことがわかります。まあこっちは誤差程度かということで、500*3965884=1982942000なので2GB使う覚悟というかリソースがあればメモリに載ってしまいます。案外なんとかなるもんですね。

そしたらこれでいいか。

python

1 2 lst_int = list(reader_int) 3 lst_rep = list(reader_rep) 4 for line_int in lst_int: 5 for line_rep in lst_rep: 6 ### 処理内容

12桁回の実行が現実的な時間内に終わるのか? というところは別に考えないといけないのですが。

投稿2020/05/21 07:28

hayataka2049

総合スコア30935

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

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

katak

2020/05/22 08:37

ありがとうございます、ご提案いただいた形で少々時間はかかりましたが、半日ほどで計算結果を得ることができました。
guest

0

ベストアンサー

reader_rep側が1回目のループでファイルの末尾まで読み込んでしまい、2回目以降では何も読み出せなくなってしまっています。seek(0)でファイルの読み込み位置を毎回先頭にもっていけばたぶん回ると思います

Python

1with open(intron, 'r') as i, open(rep, 'r') as r: 2 reader_int = csv.reader(i, delimiter='\t') 3 reader_rep = csv.reader(r, delimiter='\t') 4 5 for line_int in reader_int: 6 r.seek(0) 7 for line_rep in reader_rep: 8 ### 処理内容

ただ、何度もストレージから読み込み直すのは無駄なので、事前にリストに格納してから2重ループを回したほうがいいような気もします。

参考:Python csv.reader: How do I return to the top of the file?

投稿2020/05/21 06:25

tachikoma

総合スコア3601

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

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

katak

2020/05/22 08:36

ありがとうございます!事前にリストに格納してから2重ループを回した結果、より早く動くようになりました。
guest

0

どー見ても提示されてないコードに不具合があるとしか見えません。
各所にprintいれて実行状況を出してみたらどうでしょう

投稿2020/05/21 06:22

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問