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

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

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

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

Q&A

解決済

2回答

1768閲覧

多重ループを抜ける方法

Looove

総合スコア11

Python 3.x

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

0グッド

1クリップ

投稿2017/12/08 09:25

編集2017/12/08 10:51

###前提・実現したいこと
多重ループの抜け方がわからないです

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

多重ループを抜ける際breakなのかsys.exitなのかその他諸々なのかどれを選択すればいいのかわかりません。

###該当のソースコード

python3

1import xlrd 2import os.path 3import numpy as np 4import itertools 5import sys 6import openpyxl 7import collections 8 9xlfile = "結果.xlsx" 10if os.path.exists(xlfile): 11 xls = xlrd.open_workbook(xlfile) 12 sheet1 = xls.sheet_by_index(0) 13 nrows = sheet1.nrows 14 ncols = sheet1.ncols 15 data = np.zeros(ncols*nrows).reshape((nrows, ncols)) 16 surablist = [] 17 atusalist = [] 18 seibunlist = [] 19 taisekilist = [] 20 kekkalist = [] 21 kekkalist4 = [] 22 kekka = [] 23 24 for r in range(0, nrows): 25 for c in range(0, ncols): 26 data[r,c] = sheet1.cell(r,c).value 27 28 for r in range(0, nrows): 29 surablist.append(data[r,0]) 30 atusalist.append(data[r,2]) 31 seibunlist.append(data[r,3]) 32 taisekilist.append(data[r,5]) 33 34 for i, _ in enumerate(surablist, 4): 35 if i == 5: 36 break 37 for j in itertools.combinations(surablist, r=i): 38 if i == 4: 39 g = int(j[0]-1) 40 u = int(j[1]-1) 41 z = int(j[2]-1) 42 a = int(j[3]-1) 43 if data[g,3] == data[u,3] and data[g,3] == data[a,3] and data[g,3] == data[z,3] and data[u,3] == data[z,3] and data[a,3] == data[u,3] and data[z,3] == data[a,3] and data[g,2] + data[u,2] + data[z,2] + data[a,2] <= 2.0 and data[g,5] + data[u,5] + data[z,5] + data[a,5] <= 2.56: 44 kekkalist4.append(j) 45 46 47 48z = 0 49a = 0 50 51z = len(kekkalist4) 52set(map(tuple, kekkalist4)) 53for bb in range(0,z-1): 54 for bc in range(bb+1,z): 55 for bd in range(bc+1,z): 56 for be in range(bd+1,z): 57 for bf in range(be+1,z): 58 for bg in range(bf+1,z): 59 for bh in range(bg+1,z): 60 for bi in range(bh+1,z): 61 for bj in range(bi+1,z): 62 set1 = set(kekkalist4[bb]) 63 set2 = set(kekkalist4[bc]) 64 set3 = set(kekkalist4[bd]) 65 set4 = set(kekkalist4[be]) 66 set5 = set(kekkalist4[bf]) 67 set6 = set(kekkalist4[bg]) 68 set7 = set(kekkalist4[bh]) 69 set8 = set(kekkalist4[bi]) 70 set9 = set(kekkalist4[bj]) 71 a += 1 72 print(a) 73 if bool (set1&set2) == True: 74 np.delete(kekkalist4,bc) 75 sys.exit 76 elif bool (set1&set3) == True: 77 np.delete(kekkalist4,bd) 78 sys.exit 79 elif bool (set1&set4) == True: 80 np.delete(kekkalist4,be) 81 sys.exit 82 elif bool (set1&set5) == True: 83 np.delete(kekkalist4,bf) 84 sys.exit 85 elif bool (set1&set6) == True: 86 np.delete(kekkalist4,bg) 87 sys.exit 88 elif bool (set1&set7) == True: 89 np.delete(kekkalist4,bh) 90 sys.exit 91 elif bool (set1&set8) == True: 92 np.delete(kekkalist4,bi) 93 sys.exit 94 elif bool (set1&set9) == True: 95 np.delete(kekkalist4,bj) 96 sys.exit 97 elif bool (set2&set3) == True: 98 np.delete(kekkalist4,bd) 99 sys.exit 100 elif bool (set2&set4) == True: 101 np.delete(kekkalist4,be) 102 sys.exit 103 elif bool (set2&set5) == True: 104 np.delete(kekkalist4,bf) 105 sys.exit 106 elif bool (set2&set6) == True: 107 np.delete(kekkalist4,bg) 108 sys.exit 109 elif bool (set2&set7) == True: 110 np.delete(kekkalist4,bh) 111 sys.exit 112 elif bool (set2&set8) == True: 113 np.delete(kekkalist4,bi) 114 sys.exit 115 elif bool (set2&set9) == True: 116 np.delete(kekkalist4,bj) 117 sys.exit 118 elif bool (set3&set4) == True: 119 np.delete(kekkalist4,be) 120 sys.exit 121 elif bool (set3&set5) == True: 122 np.delete(kekkalist4,bf) 123 sys.exit 124 elif bool (set3&set6) == True: 125 np.delete(kekkalist4,bg) 126 sys.exit 127 elif bool (set3&set7) == True: 128 np.delete(kekkalist4,bh) 129 sys.exit 130 elif bool (set3&set8) == True: 131 np.delete(kekkalist4,bi) 132 sys.exit 133 elif bool (set3&set9) == True: 134 np.delete(kekkalist4,bj) 135 sys.exit 136 elif bool (set4&set5) == True: 137 np.delete(kekkalist4,bf) 138 sys.exit 139 elif bool (set4&set6) == True: 140 np.delete(kekkalist4,bg) 141 sys.exit 142 elif bool (set4&set7) == True: 143 np.delete(kekkalist4,bh) 144 sys.exit 145 elif bool (set4&set8) == True: 146 np.delete(kekkalist4,bi) 147 sys.exit 148 elif bool (set4&set9) == True: 149 np.delete(kekkalist4,bj) 150 sys.exit 151 elif bool (set5&set6) == True: 152 np.delete(kekkalist4,bg) 153 sys.exit 154 elif bool (set5&set7) == True: 155 np.delete(kekkalist4,bh) 156 sys.exit 157 elif bool (set5&set8) == True: 158 np.delete(kekkalist4,bi) 159 sys.exit 160 elif bool (set5&set9) == True: 161 np.delete(kekkalist4,bj) 162 sys.exit 163 elif bool (set6&set7) == True: 164 np.delete(kekkalist4,bh) 165 sys.exit 166 elif bool (set7&set8) == True: 167 np.delete(kekkalist4,bi) 168 sys.exit 169 elif bool (set7&set9) == True: 170 np.delete(kekkalist4,bj) 171 sys.exit 172 elif bool (set8&set9) == True: 173 np.delete(kekkalist4,bj) 174 sys.exit 175 else: 176 print (set1,set2,set3,set4,set5,set6,set7,set8,set9)

sys.exitの部分で一番はじめのループに戻りたいです。この記述で戻れているでしょうか。

エクセルファイルはこのようになっています
イメージ説明

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

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

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

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

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

guest

回答2

0

ベストアンサー

itertools.productを使うとループを浅くできますのでbreakもしやすいかと。

productがない時

python

1for i in range(10): 2 for j in range(5): 3 print(i, j)

productがある時

python

1from itertools import product 2 3for i, j in product(range(10), range(5)): 4 print(i, j)

productがなくても出来ること

python

1def gen_bb_to_bj(z) 2 for bb in range(0,z-1): 3 for bc in range(bb+1,z): 4 for bd in range(bc+1,z): 5 for be in range(bd+1,z): 6 for bf in range(be+1,z): 7 for bg in range(bf+1,z): 8 for bh in range(bg+1,z): 9 for bi in range(bh+1,z): 10 for bj in range(bi+1,z): 11 yield bb, bc, bd, be, bf, bg, bh, bi, bj 12 13for bb_to_bj in gen_bb_to_bj(10): 14 pass # なんかの処理

多分もっとフラットに書けるはず

組み合わせを元にループしようとしているように見えるのでitertoolsを使えばもうちょっと見通しよく書けると思うのですが、いかんせんfor文の連鎖でどんな組み合わせをループしようとしているのか分からなかったので、ここまでです。

投稿2017/12/08 09:53

編集2017/12/08 10:26
YouheiSakurai

総合スコア6142

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

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

mkgrei

2017/12/08 15:49

pythonでは特定のループを抜けて、特定のループに着陸するような処方箋は用意されておりません。 というのが回答かと思います。 関数の中に突っ込めば任意のループでリターンできますし、itertoolsによってループのネスティングを緩和せることもできます。 FORTRANではズバリ要求するようなことができますが、オブジェクト指向で正しく書かれてコードでは起こり得ない問題であるので言語定義から排除されたように思えます。
mkgrei

2017/12/08 16:58

お返事ありがとうございます。 さすがエイプリルフールですね。 FORTRANがgoto文からfor文に乗り換えたことを考えるといかに事故が多かったのかが伺えます…
LouiS0616

2017/12/08 17:28

Javaにはラベル付きbreakがありますが、正直使い勝手は良くないです。 そもそも論になりますが、やはり二重より深いループは設計上排除すべきなのでしょうね。 一重は言わずもがな、二重なら(適切にモジュール化されていれば)returnで脱出可能ですし。 goto文が欲しくなった時点で設計が怪しいような。
YouheiSakurai

2017/12/08 17:44

ですね。迷ったら`import this`とPEP8に尽きます。
guest

0

関数は呼び出さないと意味がありません。
プログラム自体を終了させていいのであれば、ですが...

Python

1sys.exit()

ただ、そのネストの多さではまともな処理速度が期待できないので、
設計自体を見直すことを強くお勧めします。

追記

参考までに、(おそらく)要件を満たす組み合わせを出力するコードです。
各要素の役割がわからないので、マジックナンバーが多いのはご容赦ください。

Python

1import random 2import itertools 3 4def flatten(dim_2): 5 return [elem for row in a_set for elem in row] 6 7# 適当にそれっぽいデータを作る 8hoge = [ 9 [random.randint(0, 1000) for _ in range(4)] 10 for _ in range(250) 11] 12 13for a_set in itertools.combinations(hoge, 9): 14 a_set = set(flatten(a_set)) 15 16 if len(a_set) != 9 * 4: 17 continue 18 19 print(a_set)

なお、結果が一意でなくてよいのなら、random.sampleを用いてもいいでしょう。

投稿2017/12/08 09:29

編集2017/12/08 10:31
LouiS0616

総合スコア35660

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

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

Looove

2017/12/08 09:46

具体的にはどの辺りを改善できそうでしょうか?
LouiS0616

2017/12/08 09:49

for文を連ねているようですが、これは何をしようとしているのでしょうか? zの長さ9の順列でしょうか?
Looove

2017/12/08 09:58

4個の数字の組み合わせが250あります。その、組み合わせの中から9個選び最終的には36個の数を抽出しようとしています。また、36個の数字は1つも同じ数字が被らないようにしたいです。
Looove

2017/12/08 10:12

先に9つの組み合わせを考えてから、条件に一致するものを抽出する方法も考えたのですが、計算量が多くなってしまうのでは?と考えやめました。一応貼っておきます… ``` for i, _ in enumerate(kekkalist4,9): if i == 10: break for k in itertools.combinations(kekkalist4, r=i): set(map(tuple, k)) for y in range(0,9): for x in range(0,9): set_ = set(k[y]) set__ = set(k[x]) if x == y: pass elif bool (set_ & set__) == True: np.delete(k,x) sys.exit if y == 8 and x == 8: print (k) ```
LouiS0616

2017/12/08 10:19

条件を満たす『36個の数字』を一組でも見つければよいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問