次のようなアイテムのリストがあります。
['T1','T2','T2','T2','T2','T3','T3' ]
次のようにプログレッシブ文字を追加して、重複の名前を変更する必要があります。
['T1','T2A','T2B','T2C','T2D','T3A','T3B']
ただし、同じアイテムが複数回出現する場合に限ります。
また、新しいリストを生成せずにそれを行うことは可能ですか?
何か案は?
次のようなアイテムのリストがあります。
['T1','T2','T2','T2','T2','T3','T3' ]
次のようにプログレッシブ文字を追加して、重複の名前を変更する必要があります。
['T1','T2A','T2B','T2C','T2D','T3A','T3B']
ただし、同じアイテムが複数回出現する場合に限ります。
また、新しいリストを生成せずにそれを行うことは可能ですか?
何か案は?
from collections import Counter
from string import ascii_uppercase as letters
def gen(L):
c = Counter(L)
for elt, count in c.items():
if count == 1:
yield elt
else:
for letter in letters[:count]:
yield elt + letter
今:
>>> L = ['T1','T2','T2','T2','T2','T3','T3']
>>> list(gen(L))
['T2A', 'T2B', 'T2C', 'T2D', 'T3A', 'T3B', 'T1']
リストがソートされていることを考慮すると、これによりリストがインプレースで変更されます。リストがソートされていない場合は、最初に次を使用してソートできますlis.sort()
。
>>> from string import ascii_uppercase
>>> from itertools import groupby
>>> from collections import Counter
>>> lis = ['T1', 'T2', 'T2', 'T2', 'T2', 'T3', 'T3']
>>> c = Counter(lis)
>>> for k, v in groupby(enumerate(lis), key = lambda x:x[1]):
l = list(v)
if c[k] > 1:
for x, y in zip(l, ascii_uppercase):
lis[x[0]] = x[1] + y
...
>>> lis
['T1', 'T2A', 'T2B', 'T2C', 'T2D', 'T3A', 'T3B']
def fix(L):
d = {}
for i in xrange(len(L)):
d[L[i]] = d.get(L[i],0)+1
if d[L[i]] > 1:
if d[L[i]] == 2: L[L.index(L[i])] += 'A'
L[i] += chr(64+d[L[i]])