web-dev-qa-db-fra.com

conversion de chaîne en tuple

J'ai besoin d'écrire une fonction qui prend une chaîne '(1,2,3,4,5), (5,4,3,2,1)' et retourne une liste de tuples du 1er et dernier élément de chaque Tuple , [(1,5), (5,1)]. Je pensais:

def f(givenstring):
    a=givenstring.split(',')
    for i in a[0:-1]:
        Tuple(int(i[0,-1]))

mais ici je suis coincé ..

24
Linus Svendsson

Vous pouvez utiliser ast.literal_eval() :

Évaluez en toute sécurité un nœud d'expression ou une chaîne contenant une expression Python. La chaîne ou le nœud fourni ne peut être composé que des structures littérales Python littérales: chaînes, nombres, tuples, listes, dict, booléens et Aucun.

Cela peut être utilisé pour évaluer en toute sécurité des chaînes contenant des expressions Python provenant de sources non fiables sans avoir besoin d'analyser les valeurs soi-même.

Dans votre exemple:

from ast import literal_eval
s = '(1,2,3,4,5),(5,4,3,2,1)'

l = literal_eval(s)
print l
# ((1, 2, 3, 4, 5), (5, 4, 3, 2, 1))

print [(x[0], x[-1]) for x in l]
# [(1, 5), (5, 1)]
59
tito

Vous pouvez utiliser eval. Je pense que ce sera le plus court.

>>> s = '(1,2,3,4,5),(5,4,3,2,1)'
>>> ts = eval(s)
>>> ts
((1, 2, 3, 4, 5), (5, 4, 3, 2, 1))
>>> tsp = [(el[0],el[-1]) for el in ts]
>>> tsp
[(1, 5), (5, 1)]

Pourtant, c'est pas une bonne pratique pour utiliser eval.

Une autre option consiste à analyser la chaîne à l'aide du module re.

>>> a = re.findall('\([^)]*\)',s)
>>> a
['(1,2,3,4,5)', '(5,4,3,2,1)']

Le modèle d'expression régulière signifie ceci:

\( #opening parenthesis
[^)]* #from 0 to infinite symbols different from )
\) #closing parenthesis

.

>>> b = [el.strip('()') for el in a]
>>> b
['1,2,3,4,5', '5,4,3,2,1']
>>> c = [el.split(',') for el in b]
>>> c
[['1', '2', '3', '4', '5'], ['5', '4', '3', '2', '1']]
>>> d = [Tuple(int(el2) for el2 in el) for el in c]
>>> d
[(1, 2, 3, 4, 5), (5, 4, 3, 2, 1)]

Vous pouvez également effectuer les opérations suivantes:

>>> [Tuple(int(i) for i in el.strip('()').split(',')) for el in s.split('),(')]
[(1, 2, 3, 4, 5), (5, 4, 3, 2, 1)]

Cette approche ne prend pas du tout de modules. Mais ce n'est pas très robuste (si la chaîne d'entrée aura une certaine incohérence, par exemple un espace entre parenthèses et virgule ...), (..., alors noter fonctionnera).

21
ovgolovin

Dans ce cas, le module ast pourrait être utile:

>>> from ast import literal_eval
>>> s = '(1,2,3,4,5),(5,4,3,2,1)'
>>> my_tuples = literal_eval(s)
>>> my_tuples
((1, 2, 3, 4, 5), (5, 4, 3, 2, 1))

Donc, my_tuples a un Tuple avec les tuples de votre chaîne. Maintenant, nous pouvons obtenir le premier et le dernier élément de tous vos tuples en utilisant une compréhension de liste:

>> new_tuples = [(t[0], t[-1]) for t in my_tuples]
>>> new_tuples
[(1, 5), (5, 1)]
5
juliomalegria