Parse a tuple from a string?

PythonPython 2.7

Python Problem Overview


Say I have a string that's of the same form a tuple should be, for example, "(1,2,3,4,5)". What's the easiest way to convert that into an actual tuple? An example of what I want to do is:

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

Just running tuple() on the string make the whole thing one big tuple, whereas what I'd like to do is comprehend the string as a tuple. I know I can use a regex for this, but I was hoping there's a less costly way. Ideas?

Python Solutions


Solution 1 - Python

It already exists!

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

Be aware of the corner-case, though:

>>> make_tuple("(1)")
1
>>> make_tuple("(1,)")
(1,)

If your input format works different than Python here, you need to handle that case separately or use another method like tuple(int(x) for x in tup_string[1:-1].split(',')).

Solution 2 - Python

I would recommend using literal_eval.

If you are not comfortable with literal_eval or want to have more control on what gets converted you can also disassemble the string, convert the values and recreate the tuple.

Sounds more complicated than it is, really, it's a one-liner:

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

This would throw a ValueError if any element (string) in the tuple is not convertible to int, like, for example the '1.2' in the string: '(1.2, 3, 4)'.


The same can be achieved with regex:

import re
eg = '(102,117,108)'
et_tuple = tuple(map(int, re.findall(r'[0-9]+', eg)))

Solution 3 - Python

You can parse your string without SyntaxError

def parse_tuple(string):
    try:
        s = eval(string)
        if type(s) == tuple:
            return s
        return
    except:
        return

This function return the Tuple if parse is success. Otherwise return None.

print parse_tuple("('A', 'B', 'C')")

Solution 4 - Python

We can also parse it by ourself. Let's say we have tuple returned by Python like below:

((2, 'C/C++', 0, 'clang_cpp'), (3, 'Python相关', 0, 'python'))

Here're how we do it

First, we keep reading the characters in the tuple string but stores the last left semicolon's position and how many semicolons we have meet (we can call it left semicolon level, as so for right semicolons), whenever we meet a right semicolon, we do things below:

  1. Take a substring from last semicolon to current right semicolon.(In this substring, there is no more semicolons, we just split it into array by ",". Let's say the new array is M)
  2. Then we append M to our result array, which array will stores allM.
  3. Thirdly, delete the substring we taken from the original string. Finally, do the same things like step 1 till the right and left semicolon's level comes to 0.

JavaScript code is like below:

function parseTuple(t){
    var lc = "(";
    var rc = ")";
    var lc_level = 0;
    var rc_level = 0;
    var last_lc = 0;
    var last_rc = 0;
    var result = [];
    for(i=0;i<t.length;i++){
        if(t[i] == lc){
            lc_level++;
            last_lc = i;
        }else if(t[i] == rc){
            rc_level++;
            last_rc = i;
        }
        if(rc_level == 1){
            var substr = t.slice(last_lc+1,last_rc);
            var data = substr.split(",");
            result.push(data);
            lc_level--;
            rc_level--;
            i = 0;
            t = t.slice(0,last_lc) + t.substring(last_rc+1);
        }
        if(lc_level == rc_level && lc_level==0){
            break;
        }
    }
    return result;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEliView Question on Stackoverflow
Solution 1 - PythonNiklas B.View Answer on Stackoverflow
Solution 2 - PythonjojoView Answer on Stackoverflow
Solution 3 - PythonShameemView Answer on Stackoverflow
Solution 4 - PythonhcnakView Answer on Stackoverflow