2010-05-14 5 views
4

Voici une liste contenant les doublons:Comment ajouter des numéros de comptage à des doublons dans une liste en Python?

l1 = ['a', 'b', 'c', 'a', 'a', 'b']

Voici le résultat souhaité:

l1 = ['a', 'b', 'c', 'a_1', 'a_2', 'b_1']

Comment les doublons renommer en ajoutant un numéro de compte?


Voici une tentative pour atteindre cet objectif; Cependant, y a-t-il un moyen plus pythonien?

for index in range(len(l1)): 
    counter = 1 
    list_of_duplicates_for_item = [dup_index for dup_index, item in enumerate(l1) if item == l1[index] and l1.count(l1[index]) > 1] 
    for dup_index in list_of_duplicates_for_item[1:]: 
     l1[dup_index] = l1[dup_index] + '_' + str(counter) 
     counter = counter + 1 
+0

Je suppose que vous voulez 'a_1' plutôt que 'a'_1? – exupero

+0

Yep désolé son 'a_1' =) – myeu2

Répondre

5

je ferais quelque chose comme ceci:

a1 = ['a', 'b', 'c', 'a', 'a', 'b'] 
a2 = [] 

d = {} 

for i in a1: 

    d.setdefault(i, -1) 
    d[i] += 1 

    if d[i] >= 1: 
     a2.append('%s_%d' % (i, d[i])) 
    else: 
     a2.append(i) 

print a2 
1

Je pense que la sortie que vous demandez est lui-même en désordre, et donc il n'y a aucun moyen propre de créer.

Comment comptez-vous utiliser cette nouvelle liste? Est-ce qu'un dictionnaire de comptes comme le suivant fonctionne à la place?

{'a':3, 'b':2, 'c':1} 

Si oui, je recommande:

from collections import defaultdict 
d = defaultdict(int) # values default to 0 
for key in l1: 
    d[key] += 1 
+0

Hey! Merci pour toutes vos réponses. =) La raison pour laquelle je veux conserver les doublons est que la liste sera en réalité une liste de clés qui seront utilisées par un dictionnaire et que je ne veux pas écraser la même clé involontairement. =) – myeu2

17

En Python, la génération d'une nouvelle liste est généralement beaucoup plus facile que de changer une liste existante. Nous avons des générateurs pour le faire efficacement. Un dict peut garder le compte des occurrences.

l = ['a', 'b', 'c', 'a', 'a', 'b'] 

def rename_duplicates(old): 
    seen = {} 
    for x in old: 
     if x in seen: 
      seen[x] += 1 
      yield "%s_%d" % (x, seen[x]) 
     else: 
      seen[x] = 0 
      yield x 

print list(rename_duplicates(l)) 
+0

+1 J'ai écrit la même solution en classe, mais c'est mieux, les générateurs sont plus pythoniques qu'une classe pour ce genre de travail, comme je le vois de toute façon. – daramarak

+0

Cette solution a fonctionné pour moi, mais je voulais ajouter une lettre au lieu d'un nombre. 'vu [x] + = 1; character = str (chr (96 + vu [x])); céder "% s_% s"% (x, caractère); ' –

0

Sur la base de votre commentaire à @mathmike, si votre but ultime est de créer un dictionnaire à partir d'une liste avec les clés en double, je voudrais utiliser un defaultdict des `collections Lib.

>>> from collections import defaultdict 
>>> multidict = defaultdict(list) 
>>> multidict['a'].append(1) 
>>> multidict['b'].append(2) 
>>> multidict['a'].append(11) 
>>> multidict 
defaultdict(<type 'list'>, {'a': [1, 11], 'b': [2]}) 
Questions connexes