web-dev-qa-db-fra.com

Analyser un tuple d'une chaîne?

Supposons que je dispose d'une chaîne de la même forme qu'un tuple, par exemple, "(1,2,3,4,5)". Quel est le moyen le plus simple de convertir cela en un tuple réel? Un exemple de ce que je veux faire est:

tup_string = "(1,2,3,4,5)"
tup = make_Tuple(tup_string)

Lancer simplement Tuple() sur la chaîne fait que le tout est un grand Tuple, alors que ce que j'aimerais faire, c'est comprendre la chaîne comme un Tuple. Je sais que je peux utiliser un regex pour cela, mais j'espérais qu'il existe un moyen moins coûteux. Des idées?

45
Eli

Il existe déjà !

>>> from ast import literal_eval as make_Tuple
>>> make_Tuple("(1,2,3,4,5)")
(1, 2, 3, 4, 5)

Soyez conscient du corner-case, cependant:

>>> make_Tuple("(1)")
1
>>> make_Tuple("(1,)")
(1,)

Si votre format d'entrée fonctionne différemment de Python ici, vous devez gérer ce cas séparément ou utiliser une autre méthode comme Tuple(int(x) for x in tup_string[1:-1].split(',')).

99
Niklas B.

Vous pouvez analyser votre chaîne sans SyntaxError

def parse_Tuple(string):
    try:
        s = eval(string)
        if type(s) == Tuple:
            return s
        return
    except:
        return

Cette fonction retourne la Tuple si l'analyse est un succès. Sinon, retournez None.

print parse_Tuple("('A', 'B', 'C')")
1
Shameem

Je recommanderais d'utiliser literal_eval.

Si vous n'êtes pas à l'aise avec literal_eval ou voulez avoir plus de contrôle sur ce qui sera converti, vous pouvez également désassembler la chaîne, convertir les valeurs et recréer le Tuple. 

Cela semble plus compliqué que ce n'est vraiment, c'est un one-liner:

eg = '(102,117,108)'
eg_Tuple = map(int, eg.replace('(','').replace(')','').split(',')))

Cela jetterait un ValueError si un élément (chaîne) du tuple n'est pas convertible en int, comme par exemple le '1.2' dans la chaîne: '(1.2, 3, 4)'.


La même chose peut être réalisée avec regex :

import re
eg = '(102,117,108)'
et_Tuple = Tuple(map(int, re.findall(r'[0-9]+', eg)))
1
jojo