1
   devices = [
    'SWTEST1-3AA-02',
    'SWTEST1-3AA-02',
    'SWTEST1-2CA-01',
    'SWTEST1-2CA-01',
    'SWTEST1-2AA-02',
    'SWTEST1-2AA-02',
    'SWTEST1-2AA-02'
  ]

The output that I'm looking for is as follows.

[
'SWTEST1-3AA-02',
'SWTEST1-3AA-02-2',
'SWTEST1-2CA-01',
'SWTEST1-2CA-01-2',
'SWTEST1-2AA-02',
'SWTEST1-2AA-02-2',
'SWTEST1-2AA-02-3'
]

I tried with a for loop and a counter but I'm not getting the results I want, any help will be much appreciated.

For loops that I tried:

counter = 1
out = []
for e in devices:
    out.append(f"{e}-{counter}")
    counter += 1
print(out)
out = []

d = {}

for i in devices:
    counter = 1
    d.setdefault(i, -1)
    d[i] += 1

    if d[i] >= 1:
        out.append('{}-{}'.format(i, d[i]))
        counter += 1
    else:
        out.append(i)

print(out)
Pzrk
  • 21
  • 5
  • 3
    It would probably be helpful to show what you tried and what didn't work about it. – Jon Kiparsky Apr 28 '21 at 16:55
  • 1
    Any answer is going to involve loops and counters. Please post what you've tried and what went wrong. – Woodford Apr 28 '21 at 16:55
  • I added some examples that I've used – Pzrk Apr 28 '21 at 17:03
  • Does this answer your question? [Python: Rename duplicates in list with progressive numbers without sorting list](https://stackoverflow.com/questions/30650474/python-rename-duplicates-in-list-with-progressive-numbers-without-sorting-list) – Pranav Hosangadi Apr 28 '21 at 17:04

4 Answers4

6

You can use a list comprehension:

devices = ['SWTEST1-3AA-02', 'SWTEST1-3AA-02', 'SWTEST1-2CA-01', 'SWTEST1-2CA-01', 'SWTEST1-2AA-02', 'SWTEST1-2AA-02', 'SWTEST1-2AA-02']
r = [a if not (s:=sum(j == a for j in devices[:i])) else f'{a}-{s+1}'
    for i, a in enumerate(devices)]

Output:

['SWTEST1-3AA-02', 
 'SWTEST1-3AA-02-2', 
 'SWTEST1-2CA-01', 
 'SWTEST1-2CA-01-2', 
 'SWTEST1-2AA-02', 
 'SWTEST1-2AA-02-2', 
 'SWTEST1-2AA-02-3']
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
1

Another solution:

devices = [
    "SWTEST1-3AA-02",
    "SWTEST1-3AA-02",
    "SWTEST1-2CA-01",
    "SWTEST1-2CA-01",
    "SWTEST1-2AA-02",
    "SWTEST1-2AA-02",
    "SWTEST1-2AA-02",
]

out, cnt = [], {}
for d in devices:
    if d not in cnt:
        cnt[d] = 1
    else:
        cnt[d] += 1
        d = d + "-{}".format(cnt[d])
    out.append(d)

print(out)

Prints:

['SWTEST1-3AA-02', 
 'SWTEST1-3AA-02-2', 
 'SWTEST1-2CA-01', 
 'SWTEST1-2CA-01-2', 
 'SWTEST1-2AA-02', 
 'SWTEST1-2AA-02-2', 
 'SWTEST1-2AA-02-3']
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • 1
    This is a similar code that I tried to write, looks like I did couple of steps wrong, thank you! – Pzrk Apr 28 '21 at 17:07
0

If you don't care about preserving the original order of the list, something like this would work (and is nice and simple, and works in linear time)

counter = Counter(devices)
result = []
for value, count in counter.items():
    result.append(value)
    for i in range(2, count+1): 
        result.append("{}-{}".format(value, i))
Jon Kiparsky
  • 7,499
  • 2
  • 23
  • 38
0

This should do what you want:

from collections import Counter

result = [(t+(f'-{i+1}' if i>0 else '')) for t,count in Counter(devices).items() for i in range(count)]

If ordering is important, however, this won't work, and you may need something more involved. (By this I mean that the final output will have duplicate values grouped together, rather than in the order they appear in the original list)

If you want to ordering maintained, you want something like:

def number_duplicates(values):
    counter = Counter()

    for v in values:
        counter[v] += 1
        if counter[v]>1:
            yield v+f'-{counter[v]}'
        else:
            yield v

result = list(number_duplicates(devices))

And now the result will have the same ordering of values as the original, but with the duplicate counters appended.

Gebodal
  • 345
  • 2
  • 12