преобразование строки в кортеж - PullRequest
23 голосов
/ 13 декабря 2011

Мне нужно написать функцию, которая принимает строку '(1,2,3,4,5), (5,4,3,2,1)' и возвращает список кортежей 1-го и последнего элемента каждого кортежа, [(1,5), (5,1)]. Я думал:

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

но вот я застрял ..

Ответы [ 3 ]

59 голосов
/ 13 декабря 2011

Вы можете использовать ast.literal_eval():

Безопасное вычисление узла выражения или строки, содержащей выражение Python. Предоставленная строка или узел могут состоять только из следующих литеральных структур Python: строк, чисел, кортежей, списков, диктов, логических значений и None.

Это можно использовать для безопасной оценки строк, содержащих выражения Python из ненадежных источников, без необходимости разбора значений самостоятельно.

В вашем примере:

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)]
20 голосов
/ 13 декабря 2011

Вы можете использовать eval. Я думаю, что это будет самый короткий.

>>> 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)]

Тем не менее, не рекомендуется использовать eval.

Другой вариант - проанализировать строку с помощью модуля re.

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

Шаблон регулярного выражения означает это:

\( #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)]

Также вы можете сделать следующее:

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

Этот подход вообще не требует модулей. Но это не очень надежно (если входная строка будет иметь некоторую несогласованность, например, пробел между круглыми скобками и запятой ...), (..., то замечание будет работать).

5 голосов
/ 13 декабря 2011

В этом случае может быть полезен модуль ast:

>>> 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))

Итак, my_tuples имеет кортеж с кортежами вашей строки. Теперь мы можем получить первый и последний элемент всех ваших кортежей, используя понимание списка:

>> new_tuples = [(t[0], t[-1]) for t in my_tuples]
>>> new_tuples
[(1, 5), (5, 1)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...