python
1lis = ["hoge","hogehoge","fuga","fugafuga","hoge","fuga"] 2 3for i in lis: 4 if i in lis[:lis.index(i)]: 5 i += "_2" 6print(lis)
のようなコードで
python
1["hoge","hogehoge","fuga","fugafuga","hoge_2","fuga_2"]
のような出力を得たいですがうまくいかないです(エラーは出ないが出力が変わらない)。各要素の最大重複は2なので一回判定できればいいのですが...
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー決定後に失礼します。
他の回答者の方々の回答を参考に、リスト内包表記で書いてみました。
python3
1[x + ['', '_2'][x in lis[0:i]] for i, x in enumerate(lis)]
- 動作確認用Repl.it: https://repl.it/@jun68ykt/Q231461
投稿2019/12/24 08:05
総合スコア9058
0
重複数が 2 より大きい場合や _2 に変更した文字がすでに元のリストに存在していた場合にも対応させてみました。
tt.py
python3
1def seq_for_duplicat(lis): 2 ans = [] 3 for x in lis: 4 if not x in ans: 5 ans.append(x) 6 continue 7 8 idx = 2 9 while True: 10 x_seq = x + "_" + str(idx) 11 if not x_seq in ans: 12 break 13 idx += 1 14 ans.append(x_seq) 15 16 return ans 17 18lis = ["hoge", "hogehoge", "fuga","fugafuga", "hoge", "fuga"] 19print(lis) 20print(seq_for_duplicat(lis)) 21 22lis = ["hoge", "hogehoge", "fuga","fugafuga", "hoge", "fuga", 23 "hoge", "fuga", "hoge", "fuga", 24 "hoge_2", "hoge_2", "hoge_2_3"] 25print(lis) 26print(seq_for_duplicat(lis)) 27
追記:
jun68ykt さんの回答を元に、一行にしてみました。
python3
1>>> lis = ["hoge","hogehoge","fuga","fugafuga","hoge","fuga", "hoge","fuga"] 2>>> [x + "_" + str(lis[0:i].count(x) + 1) if lis[0:i].count(x) > 0 else x for i, x in enumerate(lis)] 3['hoge', 'hogehoge', 'fuga', 'fugafuga', 'hoge_2', 'fuga_2', 'hoge_3', 'fuga_3'] 4>>>
投稿2019/12/27 01:35
編集2019/12/27 22:44総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
python
1lis = ["hoge","hogehoge","fuga","fugafuga","hoge","fuga"] 2 3for i, x in enumerate(lis): 4 before = [y for y in lis[:i] if y == x] 5 if len(before) > 0: 6 print(x + "_" + str(len(before) + 1)) 7 else: 8 print(x)
結果:
python
1hoge 2hogehoge 3fuga 4fugafuga 5hoge_2 6fuga_2
投稿2019/12/24 06:21
総合スコア6
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ループしながらin-placeで処理するのはPythonでは意外と面倒です。i += "_2"
で変数i
に束縛されている文字列は望みのものになりますが、i
に新しい文字列オブジェクトが割り当てられるだけでリストには影響しません。どうしてもやりたければ、添字を使います。
また、そのロジックもうまく動いていないようです(indexの数字を見てみましょう)。
ということで以下の方針で書いてみました。
- in-placeで処理するのはやめて、別に結果のリストを作ることにする
- index使うとかえって難しいし線形探索で遅いのでsetを使う
python
1>>> lis = ["hoge","hogehoge","fuga","fugafuga","hoge","fuga"] 2>>> s = set() 3>>> result = [] 4>>> for x in lis: 5... if x in s: 6... result.append(x + "_2") 7... else: 8... s.add(x) 9... result.append(x) 10... 11>>> result 12['hoge', 'hogehoge', 'fuga', 'fugafuga', 'hoge_2', 'fuga_2'] 13
投稿2019/12/24 06:14
総合スコア30935
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
元のコードを活かすなら、こんな感じでしょうか。
Python
1lis = ["hoge","hogehoge","fuga","fugafuga","hoge","fuga"] 2 3for i, e in enumerate(lis): 4 if e in lis[:i]: 5 lis[i] += "_2" 6 7print(lis)
lisがもっと長いなら、次のように別途記憶領域を用意した方が効率的です。
Python
1lis = ["hoge","hogehoge","fuga","fugafuga","hoge","fuga"] 2 3appeared = set() 4for i, e in enumerate(lis): 5 if e in appeared: 6 lis[i] += "_2" 7 else: 8 appeared.add(e) 9 10print(lis)
追記
こんなふうにも書けます。
Python
1work_set = set() 2lis = [e + '_2' if e in work_set else work_set.add(e) or e for e in lis] 3print(lis)
でもあんまり行儀の良いコードでは無いですね。避けた方が良いでしょう。
投稿2019/12/24 06:03
編集2019/12/24 10:33総合スコア35668
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。