Cela fait quelques heures que je suis coincé avec ceci: J'ai une série appelée size_col de 887 éléments et je veux récupérer à partir des tailles: S, M, L, XL. J'ai essayé 2 approches différentes, la compréhension de la liste et une simple boucle if elif, mais les deux tentatives ne fonctionnent pas.

sizes = ['S', 'M', 'L', 'XL']

tshirt_sizes = []
[tshirt_sizes.append(i) for i in size_col if i in sizes]

Deuxième essai:

sizes = []
for i in size_col:
if len(i) < 15:
   sizes.append(i.split(" / ",1)[-1])
else:
   sizes.append(i.split(" - ",1)[-1])

J'ai créé deux conditions car dans certains cas, la taille suit le ' - ' et dans certains autres, c'est un '/'. Honnêtement, je ne sais pas comment gérer cela.

Exemple de liste:

T-Shirt Donna "Si dai. Ciao." - M
T-Shirt Donna "Honey" - L
T-Shirt Donna "Si dai. Ciao." - M
T-Shirt Donna "I do very bad things" - M
T-Shirt Donna "Si dai. Ciao." - M
T-Shirt Donna "Stai nel tuo (mind your business)" - White / S
T-Shirt Donna "Stay Stronz" - White / L
T-Shirt Donna "Stay Stronz" - White / M
T-Shirt Donna "Si dai. Ciao." - S
T-Shirt Donna "Je suis esaurit" - Black / S
T-Shirt Donna "Si dai. Ciao." - S
T-Shirt Donna "Teamo - Tequila" - S / T-Shirt
0
sanna 12 avril 2018 à 12:05

3 réponses

Meilleure réponse

Vous aurez besoin des expressions régulières ici. Précompilez un modèle d'expression régulière, puis utilisez pattern.search dans une liste de compréhension.

sizes = ['S', 'M', 'L', 'XL']
p = re.compile(r'\b({})\b'.format('|'.join(sizes))) 

tshirt_sizes = [p.search(i).group(0) for i in size_col]
print(tshirt_sizes)
['M', 'L', 'M', 'M', 'M', 'S', 'L', 'M', 'S', 'S', 'S', 'S']

Pour plus de sécurité, vous voudrez peut-être une boucle à la place - la compréhension des listes n'est pas bonne avec la gestion des erreurs:

tshirt_sizes = []
for i in size_col:
    try:
        tshirt_sizes.append(p.search(i).group(0))
    except AttributeError:
        tshirt_sizes.append(None)

Vraiment, la seule raison d'utiliser l'expression régulière ici est de gérer correctement la dernière ligne de vos données. En général, si vous le pouvez, vous devriez préférer l'utilisation d'opérations de chaîne (à savoir str.split) sauf si elles sont évitables, elles sont beaucoup plus rapides et lisibles que la correspondance et l'extraction de modèles basés sur des expressions régulières.

3
cs95 12 avril 2018 à 10:41

Vous pouvez faire quelque chose comme ça:

available_sizes = ["S", "M", "L", "XL"]
sizes = []

for i in size_col:
    for w in i.split():
        if w in available_sizes:
            sizes.append(w)

Cela ne fonctionnerait pas si le texte contient les mots dans available_sizes plus d'une fois, par exemple T-Shirt Donna "La S è la più bella consonante" - M, car il ajouterait à la fois S et M à la liste.


Réponse originale, avant que OP ne précise que la taille n'est pas toujours le dernier mot.

Presque. Il suffit de diviser la chaîne en mots et de prendre le dernier.

sizes = []
for i in size_col:
    sizes.append(i.split()[-1])
0
Gianluca Micchi 12 avril 2018 à 09:23

Il y a deux aspects à cette question, 1) la meilleure méthode de bouclage sur l'élément et 2) la bonne façon de diviser la chaîne.

Dans le cas général, la compréhension des listes est probablement la bonne approche pour ce type de problème, mais vous avez correctement identifié que le fractionnement correct de la chaîne est délicat.

Pour ce type de problème, les expressions régulières sont très puissantes et (au risque de compliquant cela par rapport aux réponses précédentes), vous pouvez utiliser quelque chose comme:

import re
pattern = re.compile(r'[-/] (A-Z)$') # select any uppercase letters after either - or / and a space and before the end of the line (marked by $)

sizes = [pattern.search(item).group(1) for item in size_col] # group 1 selects the set of characters in the first set of parentheses (the letters)

Modifié: vient de voir la modification des articles indiquant que l'élément n'est pas toujours à la fin, et la réponse de COLDSPEED reproduit celle-ci ...

0
EdR 12 avril 2018 à 09:25