1
votes

Ajout d'espaces pour dupliquer des éléments dans la liste

J'ai la liste suivante1:

from collections import Counter
d =  Counter(list1) 
res = [k for k, v in d.items() if v > 1]
print([ f'{x} ' for x in res ])

Je voudrais ajouter un espace pour dupliquer les valeurs afin d'obtenir la sortie suivante:

[ f'{x} ' for x in list1 if .... ]

Comme Tom est répété 2 fois le 1er, il a un espace I et le second 2 espaces à la fin

J'avais un truc en utilisant une ligne de code comme celle-ci

['Tom', 'Michael', 'Tom ', 'Tom  ']


1 commentaires

Qu'avez-vous essayé jusqu'à présent (qu'il s'agisse de boucles simples ou de compréhension de listes)?


4 Réponses :


1
votes

Ceci donne la sortie que vous voulez:

[x[y] + " "*x[:y].count(x[y]) for y in range(len(x))]

Cela donne az de ['Tom', 'Michael', 'Tom', 'Tom']

En tant que compréhension de liste, cela ressemble à:

x = ['Tom', 'Michael', 'Tom', 'Tom']
z=[]
for y in range(len(x)):
    z.append(x[y] + " "*x[:y].count(x[y]))


0 commentaires

1
votes

Cela semble être une bonne opportunité d'utiliser un compteur collection, comme ceci:

ans
=> ['Tom', 'Michael', 'Tom ', 'Tom  ']

L'astuce consiste à garder une trace du nombre d'occurrences du nom en utilisant le Counter , et mettez-le à jour au fur et à mesure. Notez que la partie '' * nums [nom] dit simplement: "imprimer ce nombre d'espaces". Cela fonctionne comme prévu:

from collections import Counter

lst = ['Tom', 'Michael', 'Tom', 'Tom']
nums = Counter()
ans = []

for name in lst:
    ans.append(name + ' ' * nums[name])
    nums[name] += 1


0 commentaires

3
votes

parce que vous souhaitez ajouter des espaces comme nombre d'occurrences jusqu'à chaque élément, vous pouvez utiliser count méthode des listes. Multipliez ensuite ce nombre par "" :

l = ['Tom', 'Michael', 'Tom', 'Tom']

res = []
d = {}
for x in l:
    res.append(x + " "*d.setdefault(x, 0))
    d[x] += 1

Ou en une seule ligne:

from collections import defaultdict

l = ['Tom', 'Michael', 'Tom', 'Tom']

res = []
d = defaultdict(int)
for x in l:
    cnt = d[x]
    res.append(x + " "*cnt)
    d[x] = cnt + 1

Et les deux donnent comme attendu:

['Tom', 'Michael', 'Tom ', 'Tom  ']

Une autre approche différente peut être d'utiliser defaultdict et " Remember " les décomptes en une seule fois ( O (n) code >), au lieu de compter pour chaque élément ( O (n ^ 2) ):

res = [l[i] + " " * l[:i].count(l[i]) for i in range(len(l))]

De cette façon si un élément est vu pour le premier heure à laquelle son décompte sera initialisé à 0.


Ou, enfin, sans aucune importation. Nous pouvons simplement utiliser un dictionnaire normal et profiter de setdefault méthode:

l = ['Tom', 'Michael', 'Tom', 'Tom']

res = []
for i in range(len(l)):
    cnt = l[:i].count(l[i])
    res.append(l[i] + " "*cnt)


0 commentaires

0
votes

Voici une solution qui évite d'utiliser à plusieurs reprises le nombre sur la liste d'origine.

Nous construisons la liste de sortie, en gardant une trace avec un collections.Counter des éléments précédemment rencontrés:

from collections import Counter

data = ['Tom', 'Michael', 'Tom', 'Tom']

out = []
counts = Counter()
for item in data:
    out.append(item + ' '*counts[item])
    counts.update((item,))

print(out)
# ['Tom', 'Michael', 'Tom ', 'Tom  ']

Notez la virgule dans count.update ((item,)) : comme la mise à jour attend un itérable, nous lui passons un tuple contenant un seul élément, notre item . Passer directement la chaîne compterait les lettres individuelles.


0 commentaires