2010-07-29 6 views
1

Je dois traiter les données de la station météorologique dans un format comme celui-ci (SYNOP), où chaque ligne représente une mesure et j'ai des milliers de mesures:Python: Localiser 3 éléments de la liste adjacente et déterminer l'index de la liste

line = 'AAXX 01004 60265 32970 03404 10048 20010 38997 48605 51014=' 

a partir du bloc 6, les blocs sont numérotés (1xxxx 2xxxx 3xxxx etc, parfois seulement 5 pâtés de maisons, mais parfois aussi plus avec des données supplémentaires)

le point crucial est que le nombre de blocs entre la AAXX et le bloc 1xxxx n'est pas toujours le même, mais je sais que 2 blocs avant le bloc 1xxxx il y a des données dont j'ai besoin. Pour localiser ce bloc de manière fiable, il me faudrait déterminer la position du bloc 1xxxx et compter à rebours à partir de là.

Mon idée est de diviser la ligne le long des espaces en une liste, puis de parcourir les éléments de la liste pour trouver la position dans la liste du bloc 1xxxx.

list = line.split(' ') 

Mais je ne sais pas comment faire cette itération. Il doit y avoir une manière raisonnablement élégante de chercher 3 blocs où le premier commence par 1, le second avec 2, et le troisième avec 3, puis retourne l'index de liste du premier bloc?

Cela peut être très simple, mais je suis incapable de comprendre, et je serais reconnaissant pour tous les conseils! EDIT: Pour clarifier, il est possible qu'un autre bloc commençant par 1 apparaisse avant celui dont j'ai besoin, donc le seul moyen fiable de localiser le bloc dont j'ai besoin est de m'assurer qu'il est suivi par un qui commence par 2 et un autre cela commence par 3 (cela devrait réduire la chance d'un faux positif à peu près 0).

+0

Je pense que ce serait meilleur et plus sûr pour décoder le format SYNOP correctement –

+0

Gnibbler: Je suis d'accord. Connaissez-vous SYNOP et avez des pointeurs? Il me semble que le format n'est pas bien défini et les stations météo ne suivent pas forcément les spécifications, mais l'approche consistant à utiliser le premier bloc 1xxxx comme point de référence pour ensuite décoder le format a semblé un bon compromis, mais nécessite un robuste manière de le localiser. – stff00

Répondre

1

Il existe plusieurs façons de procéder. Une façon serait de rechercher dans la liste pour l'index et soustraire deux:

list[ (i for i, j in enumerate(list) if j.startswith("1")).next() - 2 ] 

Une autre façon serait de faire correspondre une expression régulière sur le (unsplit) chaîne:

import re 
re.search("\d{5}(?= \d{5} 1\d{4} 2\d{4} 3\d{4})", line) 

Cela correspond à un bloc de cinq chiffres, tant qu'il est suivi de 1xxxx 2xxxx 3xxxx où x est un chiffre.

+0

Merci - J'aurais dû clarifier qu'il est possible qu'un autre bloc commençant par 1 apparaisse avant celui dont j'ai besoin, donc le seul moyen fiable de localiser le bloc dont j'ai besoin est de m'assurer qu'il est suivi d'un bloc commençant par 2 et un autre cela commence par 3 (cela devrait réduire la chance d'un faux positif à peu près 0). Peut-être qu'avec regex je pourrais faire ça? – stff00

+0

Modifié l'expression rationnelle pour vous. – katrielalex

+0

Regex fait ce que je voulais faire, et c'est plus facile que d'itérer sur une liste aussi. Merci! Votre code manque un crochet de fermeture et un espace, cependant, il devrait indiquer: re.search ("\ d {5} (? = \ D {5} 1 \ d {4} 2 \ d {4} 3 \ d {4}) ", ligne) – stff00

0

itérer sur une liste est très simple:

l = line.split(' ') 
for element in l: 
    # element is now one of the strings from your list 
    if element[0] == "1": 
    print "This block begins by 1" 
Questions connexes