[Solved] Find same elements in a list, and then change these elemens to tuple (f.e. 2 to (2,1))


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))