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

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

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

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

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Python

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

Q&A

解決済

1回答

1078閲覧

Pythonのfor-elseをSwiftへ書き換えるには

LIATARET

総合スコア17

for

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

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Python

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

0グッド

1クリップ

投稿2021/01/06 13:34

編集2021/01/06 13:47

Pythonのfor-else文をSwiftに書き換えようとしています。

python

1import itertools 2 3def getResult(ary, tgt, ptn): 4 result = [] 5 for n, _ in enumerate(ary, 1): 6 for c in itertools.combinations(ary, n): 7 if sum(c) == tgt: 8 if len(result) == ptn: break 9 result.append(list(c)) 10 else: continue # ←ココと 11 break       # ココです

swift

1import Algorithms 2import Foundation 3 4func getResult(_ ary: [Float], _ tgt: Float, _ ptn: Int) { 5 var result: [[Float]] = [] 6 for n in 1 ... ary.count { 7 for c in ary.combinations(ofCount: n) { 8 if c.reduce(0, +) == tgt { 9 if result.count == ptn { break } 10 if result.contains(c) { continue } 11 result.append(contentsOf: [c]) 12 } 13 } 14 } 15 print(result) 16} 17getResult([1.0, 1.0, 1.1, 1.1, 1.2, 1.3, 1.3, 1.4, 1.5, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0], 4.0, 20)

getResultの配列aryの要素一つから順に全ての要素を組み合わせて、その合計がtgtと一致するものをptn個出力させます。
上記のswiftのコードでも出力はされるのですが、pythonの"else: continue" "break"を書き換えられず、aryの要素を増やすとかなり遅くなってしまいます。
どのように書き換えたら良いでしょうか?
宜しくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Python は for に対して else を書くことができ、for の中で break せずにループを回り切ったときだけ else が実行されます。
参考: Pythonのfor文のelseの使い方|breakやcontinueとの関係 | HEADBOOST

Swift には (他の多くの言語にも) そのような構文はありませんので、機械的に翻訳するなら flag を使って書くことになると思います。

swift

1func getResult(_ ary: [Float], _ tgt: Float, _ ptn: Int) { 2 var result: [[Float]] = [] 3 for n in 1 ... ary.count { 4 var flag = true 5 for c in ary.combinations(ofCount: n) { 6 if c.reduce(0, +) == tgt { 7 if result.count == ptn { flag = false; break } 8 result.append(c) 9 } 10 } 11 if flag { continue } 12 break 13 } 14 print(result) 15}

ただし、このコードをよく見ると、やりたいことは外側のループから break することなので、Swift ではラベルを使って簡潔に書くことができます。
参考: Swiftは多重ループなどを一気にbreakできる - Qiita

swift

1func getResult(_ ary: [Float], _ tgt: Float, _ ptn: Int) { 2 var result: [[Float]] = [] 3 outerLoop: for n in 1 ... ary.count { 4 for c in ary.combinations(ofCount: n) { 5 if c.reduce(0, +) == tgt { 6 if result.count == ptn { break outerLoop } 7 result.append(c) 8 } 9 } 10 } 11 print(result) 12}

また、Swift では result.append(contentsOf: [c]) は単に result.append(c) と書くことができます。
Python の list(c) は c を一つの要素とするリストを作るのではなく、反復可能オブジェクトの各要素から新しいリストを作る (つまり、c をコピーする) 関数です。result.append(list(c)) としているのは、単に result.append(c) とすると c の参照がリストに追加され、c の要素を書き換えると result の中身も書き変わってしまうのを防ぐためかと思われます。(c を書き換えてるようには見えませんが…。) Swift の配列は値型なので、そのような心配も不要です。

投稿2021/01/06 15:26

hoshi-takanori

総合スコア7901

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

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

LIATARET

2021/01/07 13:30

フラグとラベルでの解決方法、ありがとうございます。 おかげさまでフラグの方も納得出来、ラベルでのシンプルな書き方も勉強になりました。 また、result.append(c)もご教示いただき、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問