I need to write a function that takes a string \'(1,2,3,4,5),(5,4,3,2,1)\' and returns a list of tuples of the 1st and last element of each tuple, [(1,5),(5,1)]. I was think
You can use ast.literal_eval():
Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.
In your example:
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)]
In this case, the ast
module could be useful:
>>> 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))
So, my_tuples
has a tuple with the tuples of your string. Now, we can get the first and last element of all your tuples using a list comprehension:
>> new_tuples = [(t[0], t[-1]) for t in my_tuples]
>>> new_tuples
[(1, 5), (5, 1)]
You may use eval
. I think it'll be the shortest one.
>>> 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)]
Still, it's not a good practice to use eval
.
Another option is to parse the string using re
module.
>>> a = re.findall('\([^)]*\)',s)
>>> a
['(1,2,3,4,5)', '(5,4,3,2,1)']
Regexp pattern means this:
\( #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)]
Also, you may do the following:
>>> [tuple(int(i) for i in el.strip('()').split(',')) for el in s.split('),(')]
[(1, 2, 3, 4, 5), (5, 4, 3, 2, 1)]
This approach takes not modules at all. But it's not very robust (if the input string will have some inconsistency, e.g. space between parentheses and comma ...), (...
, then noting will work).