Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 17/04/2021, à 21:03

DonutMan75

Python : trouver le premier élément selon condition

Bonjour à tous,
voilà, je dispose d'une liste X de noms, ordonnée alphabétiquement ainsi que d'un vecteur Y de réels de la même taille.
Par exemple :

'abeille'
'albatros'
'baobab'
'brise'
'cerise'
...
...

Cette liste est très longue (de l'ordre de 76000 éléments).

Je souhaite tracer l'évolution de Y (avec pyplot) et je souhaiterais modifier l'axe des X pour qu'il affiche uniquement la position de certaines lettres. Ainsi dans l'exemple (simplifié) ci-dessus, je souhaite afficher :
- le XTickLabel 'A' à l'index 0 (car ça correspond à la 1ere entrée qui commence par A, ici abeille)
- le XTickLabel 'B' à l'index 2 (pour baobab)
- et ainsi de suite

C'est plus parlant avec une image :

Exemple de plot attendu

Voici un bout d'algorithme que j'ai imaginé mais ce n'est pas tip-top je trouve.
Dans ce qui suit, names représente ma très longue suite de mots, x_val représente les lettres que je souhaite afficher en abscisse et x_ind les indices associés

x_val = list('ABC')
x_ind = []

for x in x_val:
  tmp = [k for (k, name) in enumerate(names) if name.startwith(x)]
  x_ind.append(tmp[0])

Ca marchouille mais c'est pas foufou parce que je créé à chaque fois un vecteur tmp assez gros alors que je pourrais m'arréter à la première solution trouvée.....

Y'aurait-il quelque chose de plus pythonic ?

Merci d'avance smile

Hors ligne

#2 Le 17/04/2021, à 21:36

Nuliel

Re : Python : trouver le premier élément selon condition

Bonjour,
Je propose ceci:

liste = ['abeille',
'albatros',
'baobab',
'brise',
'cerise']
premiere_lettre = 'a'
liste_index = [0]
index = 0
for nom in liste:
    if nom[0] != premiere_lettre:
        premiere_lettre = nom[0]
        liste_index.append(index)
    index += 1
print(liste_index)

qui permet de récupérer les index en profitant du tri par ordre alphabétique

Je n'ai pas l'astuce magique python malheureusement sad

Dernière modification par Nuliel (Le 17/04/2021, à 21:38)

Hors ligne

#3 Le 17/04/2021, à 22:02

Compte supprimé

Re : Python : trouver le premier élément selon condition

Bonjour,

DonutMan75 a écrit :
x_val = list('ABC')
x_ind = []

for x in x_val:
  tmp = [k for (k, name) in enumerate(names) if name.startwith(x)]
  x_ind.append(tmp[0])

Ca marchouille mais c'est pas foufou parce que je créé à chaque fois un vecteur tmp assez gros alors que je pourrais m'arréter à la première solution trouvée.....

for x in x_val:
  for k,name in enumerate(names):
      if name.startwith(x):
          x_ind.append(k)
          break

?

#4 Le 17/04/2021, à 22:34

pingouinux

Re : Python : trouver le premier élément selon condition

Bonsoir,
Autre façon de faire :

names = ['abeille',
'albatros',
'baobab',
'brise',
'cerise']
resul={}
for k,name in tuple(enumerate(names))[-1::-1]: resul[name[0]]=k
print(sorted(resul.values()))

Hors ligne

#5 Le 17/04/2021, à 22:42

DonutMan75

Re : Python : trouver le premier élément selon condition

Bonsoir,
super, merci pour vos retours très intéressants !
Bon je suis rassuré je ne suis pas passé à côté d'une fonction magique python qui aurait fait ça tout seul ^^
Néanmoins vos retours m'ont permis de voir plusieurs points d'améliorations potentiels de ce que j'avais fait. Je vais creuser ça.

Merci et bonne soirée smile

D.

Hors ligne

#6 Le 17/04/2021, à 23:28

beuguissime

Re : Python : trouver le premier élément selon condition

Salut,

Sans prétendre que ma solution est meilleure que les autres (au sens, rapidité d'exécution par exemple), voici une autre façon de faire :

import itertools
import collections

names = ['abeille', 
     'albatros', 
     'baobab', 
     'brise', 
     'cerise', 
     'daniel', 
     'jack', 
     'jolinar', 
     'hammond', 
     'samantha', 
     'simmons', 
     'tealc']

k = list(collections.Counter([v[0] for v in names]).values())
list(itertools.accumulate([0] + k[:-1]))

ce qui donne

[0, 2, 4, 5, 6, 8, 9, 11]

Ça semble marcher. smile

Hors ligne