简体   繁体   中英

Python - make non-unique items in list unique by adding count

How would I make the items in my list unique by concatenating a count, starting from 1 for each unique value?

so, for example:

sheep, sheep, tiger, sheep, hippo, tiger

becomes:

sheep1, sheep2, tiger1, sheep3, hippo1, tiger2

Here's how you could use Counter to do it.

from collections import Counter

s = ["sheep", "sheep", "tiger", "sheep", "hippo", "tiger"]
u = [ f"{a}{c[a]}" for c in [Counter()] for a in s if [c.update([a])] ]

print(u)

['sheep1', 'sheep2', 'tiger1', 'sheep3', 'hippo1', 'tiger2']

note that, if your strings can have a numeric suffix, this would not be sufficient to cover all cases (eg ['alpha']*11+['alpha1'] would repeat 'alpha11' )

you can use a simple for loop:

l = ['sheep', 'sheep', 'tiger', 'sheep', 'hippo', 'tiger']

count = {}
output = []
for s in l:
    if s in count:
        count[s] += 1
    else:
        count[s] = 1

    output.append(f'{s}{count[s]}')

output

output:

['sheep1', 'sheep2', 'tiger1', 'sheep3', 'hippo1', 'tiger2']

Using a combination of defaultdict and count :

>>> from collections import defaultdict
>>> from itertools import count
>>> s = ["sheep", "sheep", "tiger", "sheep", "hippo", "tiger"]
>>> d = defaultdict(lambda: count(1))
>>> [f'{x}{next(d[x])}' for x in s]
['sheep1', 'sheep2', 'tiger1', 'sheep3', 'hippo1', 'tiger2']

count is an object that yields ever-increasing numbers as you iterate over it; calling next gives you the next number in the sequence.

The defaultdict creates a new count instance every time you try to access a new key, while saving the newly created instance for the next time you see the same key.

I had a very similar need where the output would be:

['sheep', 'sheep1', 'tiger', 'sheep2', 'hippo', 'tiger1']

I approached it a little differently looking for an O(n) solution and extended the dictionary class.

class IncDict(dict):
    def __missing__(self,key):
        return -1

    def __getitem__(self,key):
        val = dict.__getitem__(self,key)
        val+=1
        dict.__setitem__(self,key,val)
        if val==0:
            return key
        else:
            return key+str(val)

l = ['sheep', 'sheep', 'tiger', 'sheep', 'hippo', 'tiger']
uniquify = IncDict()
[uniquify[x] for x in l]

Output:

['sheep', 'sheep1', 'tiger', 'sheep2', 'hippo', 'tiger1']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM