To just add a count you could keep a set of itertools.count
objects in a defaultdict
:
from itertools import count
from collections import defaultdict
counters = defaultdict(lambda: count(1))
result = [(n, next(counters[n])) for n in inputlist]
but this would add counts to all elements in your list:
>>> from itertools import count
>>> from collections import defaultdict
>>> counters = defaultdict(lambda: count(1))
>>> inputlist = [1, 2, 4, 3, 2, 1]
>>> [(n, next(counters[n])) for n in inputlist]
[(1, 1), (2, 1), (4, 1), (3, 1), (2, 2), (1, 2)]
This keeps your output consistent and avoids having to later test if one of these elements is an integer or a tuple.
If you have to produce tuples only for repeated elements, you’ll have to do two steps; create a count with collections.Counter()
then use the same counting trick as above but only for those elements whose total count is greater than 1:
from itertools import count
from collections import defaultdict, Counter
counters = defaultdict(lambda: count(1))
tally = Counter(inputlist)
result = [(n, next(counters[n])) if tally[n] > 1 else n for n in inputlist]
Demo:
>>> from collections import Counter
>>> counters = defaultdict(lambda: count(1))
>>> tally = Counter(inputlist)
>>> [(n, next(counters[n])) if tally[n] > 1 else n for n in inputlist]
[(1, 1), (2, 1), 4, 3, (2, 2), (1, 2)]
However, if you are trying to produce ‘unique’ keys for a dictionary, consider grouping the values instead, so instead of:
{(1, 1): foo, (1, 2): bar}
produce lists or sets:
{1: [foo, bar]}
{1: {foo, bar}}
You can do so with a defaultdict
too:
result = defaultdict(set)
for key, value in zip(keys, values):
result[key].add(value)
to produce a set per key, or use defauldict(list)
and result[key].append(value)
to produce a list.
2
solved Find same elements in a list, and then change these elemens to tuple (f.e. 2 to (2,1))