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

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

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

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

Q&A

解決済

2回答

890閲覧

.append()をすると処理したリストが元に戻ってしまう

kay_ventris4

総合スコア269

Python

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

0グッド

0クリップ

投稿2021/10/03 19:35

編集2021/10/03 19:37

#問題
イメージ説明
こちらから

#方針
SとTが完全一致の時は明らかなのでexit()します。
隣あうSの二文字を入れ替えた文字列をliに追加していって、最後にTと一致するものがあればYes,なければNoを出力します。
ここでは、liの中身を確認するところまで記述します。

#該当コード

Python

1S = list(str(input())) 2T = list(str(input())) 3 4if S == T: 5 print('Yes') 6 exit() 7 8li = [] 9for i in range(len(S) - 1): 10 S[i], S[i + 1] = S[i + 1], S[i] 11 li.append(S) 12 S[i], S[i + 1] = S[i + 1], S[i] 13 14print(li)

#質問
該当コード中のli.append(S)をprint(S)に変えて試しに出力してみると、

['b', 'a', 'c'] ['a', 'c', 'b']

のように期待されたものが得られます。

しかし、上の該当コードを実行すると、例えばS=abc, T=acbのようなテストケースに対して

[['a', 'b', 'c'], ['a', 'b', 'c']]

という出力がされます。
.append()のどのような挙動によって、せっかく処理したSが元通りになってリストに突っ込まれてしまうのでしょうか。素人質問にて恐縮ですが、ご教授のほどよろしくお願い申し上げます。

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

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

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

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

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

guest

回答2

0

ベストアンサー

公式ドキュメント FAQ なぜ list 'y' を変更すると list 'x' も変更されるのですか? で説明されている問題です。

liに1回目にappendしたSと2回目にappendしたSは全く同じリストだからです。

以下のようにコピーを使えば、これを防ぐことができます。

python

1>>> li = [] 2>>> for i in range(len(S) - 1): 3... S[i], S[i + 1] = S[i + 1], S[i] 4... li.append(S.copy()) 5... S[i], S[i + 1] = S[i + 1], S[i] 6... 7>>> print(li) 8[['b', 'a', 'c'], ['a', 'c', 'b']]

投稿2021/10/03 20:50

ppaul

総合スコア24670

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

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

0

質問への直接の回答ではありません。
質問文にある問題を解くコードを書いてみました。

1番目は質問文みあるコードを発展させた方法です。
s の 1 箇所を文字入れ替えしたものをすべて列挙し、t に一致するものがあるか? を調べています。

2番目は 上の方法では 省メモリーをめざしたものです。li の配列を使わずに済ませています。
3番目は、s == t の比較回数をへらすことをめざしたものです。
s と t を先頭から比べていき、差が出るところをみつけたら、その場所は文字入れ替えになっているかを調べます。もしそうなっていたら、残り部分をお一文字づつ一致するかを調べます。

pppp.pu

python3

1def check(s, t): 2 if s == t: 3 return True 4 5 li = [] 6 for i in range(len(s) - 1): 7 s[i + 1], s[i] = s[i], s[i + 1] 8 li.append("".join(s)) 9 s[i + 1], s[i] = s[i], s[i + 1] 10 11 print(" li=", li) 12 13 str_t = "".join(t) 14 for x in li: 15 if x == str_t: 16 return True 17 return False 18 19def check_1(s, t): 20 if len(s) != len(t): 21 return False 22 23 if s == t: 24 return True 25 26 for i in range(len(s) - 1): 27 s[i + 1], s[i] = s[i], s[i + 1] 28 if s == t: 29 return True 30 s[i + 1], s[i] = s[i], s[i + 1] 31 32 return False 33 34def check_2(s, t): 35 if len(s) != len(t): 36 return False 37 38 if s == t: 39 return True 40 41 # s と t で差が出る位置を探す 42 pos = 0 43 for i in range(len(s) - 1): 44 if s[i] != t[i]: 45 pos = i 46 break 47 48 # 文字にお入れ替えになっているか? 49 if s[pos] != t[pos + 1] or s[pos + 1] != t[pos]: 50 return False 51 52 # 残りの部分はすべて一致するか? 53 for i in range(pos + 2, len(s) - 1): 54 if s[i] != t[i]: 55 return FAlse 56 57 return TRue 58 59# S = list(str(input())) 60# T = list(str(input())) 61 62data = [ 63 ["abc", "acb"], 64 ["abc", "abc"], 65 ["abc", "ab"], 66 ["abc", "abcd"], 67 ["abcd", "abcx"], 68] 69 70print("--- check") 71for d in data: 72 s, t = list(d[0]), list(d[1]) 73 print(d, check(s, t)) 74 75print("--- check_1") 76for d in data: 77 s, t = list(d[0]), list(d[1]) 78 print(d, check_1(s, t)) 79 80print("--- check_2") 81for d in data: 82 s, t = list(d[0]), list(d[1]) 83 print(d, check_1(s, t))

実行例
イメージ説明

投稿2021/10/04 14:05

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問