+ 1

Convert string to tuple in python

I have a string like that "( (0, 0, 0), (1,1) )" which is actually a tuple of tuples. I need to convert this to a tuple data type as it is. Is there any built in stuff or should I do it manually?

13th Jul 2020, 4:01 PM
Mustafa K.
Mustafa K. - avatar
20 Answers
+ 8
Please again : DO NOT USE 'eval' function. It is too much dangerous. If your file gets corrupted, a hacker can gain control to you computer... The eval function is evil. Consider this program: a = eval(input(">>>" )) What if I write : print(__import__("os").listdir(".")) Then I can read all the file I want on your computer, with the only restriction of the script privileges. I could even open a connexion to a server and download a virus, if I would, and the whole thing in only one line and one expression. Impressive! So never use eval while working with data than can be corrupted.
13th Jul 2020, 5:27 PM
Théophile
Théophile - avatar
+ 6
The best thing to do is, to keep the code flexible for n inner tuples and for n1 elements in inner tuples. I think we can do it with regex, just cropping out each inner tuple like "(1, 2, 3)" means get everything that is in () parenthesis, so that we can put these pieces in a list. Then its not difficult to put them together to a numeric tuple. But i am not as good in regex as i like to be. 😄 So i have done a short code, that can do this task without eval(): inp1 = "( (0, 0, 0), (1,1) )" inp1 = "( (1, 2, 3, 4), (5, 6, 7))" res = [] buf = [] for i in inp1: if i in ')' and buf != []: res.append(tuple(buf)) buf = [] continue if i.isdigit(): buf.append(int(i)) fin = tuple((res[0], res[1])) print(fin)
13th Jul 2020, 6:02 PM
Lothar
Lothar - avatar
+ 3
Mustafa K. , is the input always 2 tuples in an other tuple, or can it bee like this: "((1,2,3), (4,5), (6,7))"
13th Jul 2020, 5:54 PM
Lothar
Lothar - avatar
+ 3
I have reworked my code a bit, may be you can test it eith your data: ( it works with all shape and length of tuple) #inp1 = "( (0, 0, 0), (1,1) )" inp1 = "( (1, 2, 3, 4), (5, 6, 7), (8, 9), (9, 24))" res = [] buf = [] inp1 = inp1.replace(' ','') lst = inp1[2:-2].split('),(') for i in lst: for j in i.split(','): buf.append(int(j)) res.append(tuple(buf)) buf = [] res = tuple(res) print(res)
13th Jul 2020, 7:42 PM
Lothar
Lothar - avatar
+ 2
𝐊𝐢𝐢𝐛𝐨 𝐆𝐡𝐚𝐲𝐚𝐥 I think this a the same type of question as the man who wanted to "input a list" (convert a list representation to an actual list). But I'm pretty sure there is always an alternative to the use of 'eval' (because eval is evil). However, the alternative strongly depends of the context, and I have too few info to answer correctly! We'll wait until he provides more info.
13th Jul 2020, 4:43 PM
Théophile
Théophile - avatar
+ 2
Mustafa K. Look at the code below you will get it : https://code.sololearn.com/cvdB3PmOsFb5/?ref=app I hope my code has helped you a little bit. If further any querry mention me with that. Thank you.
13th Jul 2020, 5:13 PM
Akshay Panwar
Akshay Panwar - avatar
+ 2
If you control the way the program writes to the file too, there might be a solution : changing the way data are written to the file. Here, we can see something interesting : the tuples have all the same shape ((x, y, z), (x, y)). So, instead of writing the string representation of the tuple to the file, you could write the tuple flattened, since you know the shape of the tuple. Thus, when reading the file, and because you know the shape of the tuple, you can construct this tuple again. Example : # tuple-shape = (3, 2) ~~ writing ~~ ((1, 1, 1), (0, 0)) => flatten the list and write each element separated by spaces => 1 1 1 0 0 ~~ reading ~~ 1 1 1 0 0 => read line by line, split by space => [1, 1, 1, 0, 0] => you know the shape, so rebuild the tuple : the 3 first element are the first sub-tuple, and the two last are the second sub-tuple => (1, 1, 1) and (0, 0) => group them together => ((1, 1, 1), (0, 0))
13th Jul 2020, 5:20 PM
Théophile
Théophile - avatar
+ 2
Lothar thanks, thats a nice way too
13th Jul 2020, 6:08 PM
Mustafa K.
Mustafa K. - avatar
+ 2
import re mystring = "( (0, 0, 0), (1,1) )" # mystring1 = "( (1, 2, 3, 4), (5, 6, 7), (8,9,10), (11, 12, 13)" for testing..also works. innerlist = [] outerlist = [] mylist = re.findall(r"\([0-9, ]{1,}\)", mystring) for x in mylist: for y in re.findall(r"\d+", x): innerlist.append(int(y)) outerlist.append(tuple(innerlist)) innerlist = [] mytuple = tuple(outerlist) print(mytuple)
13th Jul 2020, 9:35 PM
rodwynnejones
rodwynnejones - avatar
+ 1
Théophile but we can still change String to tuple.
13th Jul 2020, 5:22 PM
Akshay Panwar
Akshay Panwar - avatar
+ 1
Ok guys, thanks i got the solution, ill prob. use the way Théophile advised. Akshay Panwar thanks for the reply, i just didnt want to use eval func.
13th Jul 2020, 5:25 PM
Mustafa K.
Mustafa K. - avatar
13th Jul 2020, 11:42 PM
Vitaly Sokol
Vitaly Sokol - avatar
0
I have a text file that is full of tuple of tuples in this format "( (0,0,0), (1,1) )" Each line with a different value but the same type (a tuple that includes 2 tuples inside). I got all the lines in a list with, lines = file.readlines() So what i need is the tuple version of each line, so i need to convert these lines into a tuple type What I meant by as it is, is when I use tuple(line) it converts the line into a tuple with each character in the line is an item, but i need a tuple which includes 2 tuples inside as the line indicates
13th Jul 2020, 4:58 PM
Mustafa K.
Mustafa K. - avatar
0
There is no input output going on. There is a text file lets say it is just like that, text.txt ((0,0,0), (1,1)) ((1,1,1), (2,2)) ((2,2,2), (3,3)) And in the code, i open that file.txt, then take all the lines with this, lines = file.readlines() somewhere in my program i make some calculations, so each line in this text file must be converted into a list or tuple, but i want it to be tuple instead. i need something like this, for i in range(len(lines)): lines[i] = to_tuple(lines[i]) print (lines[0]) # outputs: ((0,0,0), (1,1)) print (type(lines[0]) # outputs: tuple But tuple(string) does not do what I want.
13th Jul 2020, 5:12 PM
Mustafa K.
Mustafa K. - avatar
0
Mustafa K. Is my code not as much helpful to you ? Do you have any other querry ?
13th Jul 2020, 5:20 PM
Akshay Panwar
Akshay Panwar - avatar
0
Lothar actually i got what i will do but im open to other suggestions too. The data that is written in the text file is a map of the game. And they are the coordinates of obstacles. First tuple in the tuple is a position of where it lyes and the other is being color. In map editor program i edit the map, write it to a file and read the map from game then play.
13th Jul 2020, 5:57 PM
Mustafa K.
Mustafa K. - avatar
0
Lothar and if data are written into the file as I said, it is : ~~ reading ~~ string = "1 1 1 0 0" splitted = list(map(int, string.split())) result = (tuple(splitted[0:3]), tuple(splitted[3:])) ~~ writing ~~ t = ((1, 1, 1), (0, 0)) print(*t[0], *t[1], file=the_file) I think it is way simpler and shorter 😊 And what you did was basically a simple eval function. 😁
13th Jul 2020, 6:26 PM
Théophile
Théophile - avatar
0
#it works but it uses eval :/ a = "(1,2,3)(5,6,7)(1,2,3)" def manual_parsing(x): m = (x.split(")(")) g = [] for k in m: k = k.strip("(") k = k.strip(")") g.append(eval(k)) return g print(manual_parsing(a))
14th Jul 2020, 11:29 AM
madeline
madeline - avatar
0
As bayraklari as as
14th Jul 2020, 4:47 PM
Marcos Brian
Marcos Brian - avatar
0
Burdada türk bulmusum asmazmiyim 🇹🇷🇹🇷🇹🇷🇹🇷🇹🇷🇹🇷
14th Jul 2020, 4:48 PM
Marcos Brian
Marcos Brian - avatar