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

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

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

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

5回答

1866閲覧

Pythonの配列で重複する要素を変更したい

sho0423

総合スコア31

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/12/24 05:58

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ページで確認できます。

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

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

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

guest

回答5

0

ベストアンサー決定後に失礼します。
他の回答者の方々の回答を参考に、リスト内包表記で書いてみました。

python3

1[x + ['', '_2'][x in lis[0:i]] for i, x in enumerate(lis)]

投稿2019/12/24 08:05

jun68ykt

総合スコア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
katoy

総合スコア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

TomOliver

総合スコア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

hayataka2049

総合スコア30933

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

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

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
LouiS0616

総合スコア35660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問