You can use a Counter for this to keep track of the number of times the item has been added, like:
from collections import Counter
def labelize(iterable):
c = Counter()
for item in iterable:
sc = item.casefold()
c[sc] += 1
yield '{}_{}'.format(item, c[sc])
We can then label with:
>>> list(labelize(['a', 'b', 'A', 'b', 'a', 'C', 'D', 'd']))
['a_1', 'b_1', 'A_2', 'b_2', 'a_3', 'C_1', 'D_1', 'd_2']
We can generalize the above by using an arbitrary mapping function, like:
def labelize(iterable, key=lambda x: x):
c = Counter()
for item in iterable:
ci = key(item)
c[ci] += 1
yield '{}_{}'.format(item, c[ci])
The equivalent here would be:
>>> list(labelize(['a', 'b', 'A', 'b', 'a', 'C', 'D', 'd'], str.casefold))
['a_1', 'b_1', 'A_2', 'b_2', 'a_3', 'C_1', 'D_1', 'd_2']
Note: please do not use str.lower or str.upper for case matching. Certain cultures have specific rules for case matching. For example in German, the eszett ß [wiki] has as uppercase 'SS', by using .tolower(), the two would be different). The str.casefold [Python-doc] is designed to map strings to a value that can be used for case-insensitive matching. See for more information 3.13 Default Case Algorithms of the Unicode 9 standard.
listsince it's a python reserved name[a_1, b_2, a_3, b_4, a_5, c_6, D_7, d_8]a = A?