IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Extrait une sequence entre deux caracteres


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    120
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2003
    Messages : 120
    Par défaut Extrait une sequence entre deux caracteres
    Bonjour

    Je reçois une séquence d'octet dans un buffer
    La séquence a extraire est entre les bornes
    - Start: double octet FF
    - End: octet FE
    <FF><FF><FD><21><11><32><25><0B><F8><02><91><FE>

    J'ai fait une analyse avec une boucle mais c'est lourd, j'essaye de trouver un code plus pythonesque afin d'optimiser l'extraction de la séquence

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    self.data += buffer
            if chr(0xFF) in self.data and chr(0xFE) in self.data:
                self.receivedData = [byte for byte in self.data if self.data.count(chr(0xFF)) == 2][2:self.data.index(chr(0xFE))]
                print "test ":,self.receivedData
    Mais si la selection ne comporte qu'un FF le code ne fonctionne pas
    Il y a t'il une solution pour extraire d'une liste des données entre 2 bornes

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Amha, la meilleur solution est encore de parcourir la liste une seule fois, en récupérant les données voulues, puis de faire un slice… De toute façon, des fonction comme count() parcourent aussi toute la liste, donc mieux vaut un seul parcours explicite que deux ou trois implicites*!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    self.data += buffer
    in_idx = out_idx = None
    for idx, byte in enumerate(self.data):
        if byte == chr(0xff) and in_idx is not None and idx < len(self.data) - 2 and self.data[idx + 1] == byte:
            in_idx = idx + 2
        elif byte == chr(0xfe) and in_idx and not out_idx:
            out_idx = idx
            break  # No need to go further!
    if in_idx is not None and out_idx:
        self.receivedData = self.data[in_idx:out_idx]

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    ou bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try:
      start = self.data.index('\xff\xff')
      stop = self.data.index('\xfe', start+2)
      self.receivedData = self.data[start+2:stop]
    except ValueError:
      self.receivedData = None
    [edit]
    ou encore avec une regexp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import re
    m = re.search(self.data, '\xff\xff(.*?)\xfe')
    self.receivedData = m and m.group(1)

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    120
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2003
    Messages : 120
    Par défaut
    Merci pour vos idées

    Le parcours est assez semblable à ce que j'ai fait

    Les datas reçues sont sous forme de liste pas une chaine. Le self.data.index('\xff\xff') ne fonctionne pas dans une liste, c'est le problème que je n'arrive pas à résoudre
    Je pourrai les joindre mais c'est une itération de plus

    Je n'avais pas pensez au regex, je connais peu. Ceci fonctionne sur les listes sans les mettre sous forme de chaine ?
    Est-ce gourmand en ressource. le but est d'en utiliser le moins possible

  5. #5
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Non, une regex ne marchera pas sur une liste, str-only*!

    À noter que ma solution n’est pas très gourmande en ressources, elle ne parcourt la liste qu’une seule fois (et encore, pas forcément en entier), ne crée pas beaucoup de variables de travail…

    Elle est simplement assez verbeuse (proche de ce qu’on pourrait faire en C, par exemple, en fait), mais encore une fois je ne vois pas de “raccourcis” pythonesque pour faire ça. Si c’était une str, la première solution de dividee serait probablement le meilleur compromis performance/ressources.

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    OK, il n'était pas mentionné que le "buffer" était une liste, pas une string. La solution de mont29 est nettement meilleure que ta solution d'origine car elle est plus efficace et respecte mieux la spécification.

    Toutefois, il faudrait vérifier s'il est vraiment plus coûteux de faire une première passe pour convertir les data en string (data = ''.join(self.data)). Les fonctions "builtins" sont plus rapides que des boucles explicites, et cela pourrait compenser le fait de faire deux passes au lieu d'une.

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/08/2012, 17h41
  2. [Oracle 9] Une date entre deux dates !
    Par jf-nigou dans le forum Langage SQL
    Réponses: 3
    Dernier message: 12/04/2006, 10h45
  3. Faire une division entre deux chiffres?
    Par shun dans le forum Langage SQL
    Réponses: 9
    Dernier message: 09/09/2005, 16h37
  4. Passer une variable entre deux fenêtres
    Par DeezerD dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 17/08/2005, 09h52
  5. Réponses: 14
    Dernier message: 02/05/2005, 18h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo