Home > Enterprise >  How can I rename list items so that they are all unique?
How can I rename list items so that they are all unique?

Time:11-01

I have a list like this:

lista=['a','b','b','c','d','e','c','e','b','b']

note that the list will be filled from another source, so I can't know the items nor number

what I need is this result:

['a','b','b_1','c','d','e','c_1','e_1','b_2','b_3']

I tried with recursive checks but it doesn't garantee that all recurrancies are detected... thanks in advance!!

CodePudding user response:

You can make a counter variable to keep track of how many have been seen:

lista = ['a','b','b','c','d','e','c','e','b','b']

output = []
counter = {}

for x in lista:
    if x in counter.keys():
        output.append(f"{x}_{counter[x]}")
        counter[x]  = 1
    else:
        output.append(x)
        counter[x] = 1

print(output) # ['a', 'b', 'b_1', 'c', 'd', 'e', 'c_1', 'e_1', 'b_2', 'b_3']

Or, using collections.Counter:

from collections import Counter

lista = ['a','b','b','c','d','e','c','e','b','b']

output = []
counter = Counter()
for x in lista:
    output.append(f"{x}_{counter[x]}" if counter[x] else x)
    counter.update(x)

CodePudding user response:

You could use a generator to yield modified strings:

def label_occurrences(strings):
    from collections import Counter

    counter = Counter()
    for string in strings:
        if string in counter:
            yield '{}_{}'.format(string, counter[string])
        else:
            yield string
        counter.update([string])


strings = ['a', 'b', 'b', 'c', 'd', 'e', 'c', 'e', 'b', 'b']
print(list(label_occurrences(strings)))

Output:

['a', 'b', 'b_1', 'c', 'd', 'e', 'c_1', 'e_1', 'b_2', 'b_3']
>>> 

EDIT: Slight variation specifically for filenames:

def label_occurrences(filenames):
    from collections import Counter
    from pathlib import Path

    counter = Counter()
    for filename in filenames:
        path = Path(filename)
        if path.name in counter:
            yield '{}_{}{}'.format(path.stem, counter[path.name], path.suffix)
        else:
            yield filename
        counter.update([path.name])


filenames = ['test.txt', 'foo.exe', 'test.txt', 'bar.pdf', 'foo.exe']
print(list(label_occurrences(filenames)))

CodePudding user response:

from collections import Counter 


lista=['a','b','b','c','d','e','c','e','b','b']

print([k if not i else k '_' str(i) for k,v in Counter(lista).items() for i in range(v)])    

#output: ['a', 'b', 'b_1', 'b_2', 'b_3', 'c', 'c_1', 'd', 'e', 'e_1']

CodePudding user response:

I would keep a hashmap (string to number) tracker of all the different entries and update the number as used like this:

function arrayCounter():
hashmap = {}
new_list = []

for x in list:
    if x in hashmap:
        new_list.append(x "_" hashmap[x])
        hashmap[x] = hashmap[x]  1
    else:
        new_list.append(x)
        hashmap[x] = 1
return new list
  • Related