1

I am getting input from an external device connected via Ethernet, and it is passing several values of string type e.g. value = '(2,2)\n'. I would like to assign these values to a list or tuple variable e.g. final_value = (2,2). The code I am using is the following:

import socket
sock = socket.socket()
value =sock.recv(buffersize=2048)
formatted_value = eval(value)

I read that the eval function I am using at this moment to get the list is not a very safe approach, as the external device could pass a dangerous script. So, I would like to know if there is any alternative, similar to the function int(), which can be used to get an integer from a string.

Jalo
  • 1,131
  • 1
  • 12
  • 28
  • Would the string-list always come back in the (x,x) format? – elPastor Nov 21 '16 at 12:10
  • Possible duplicate of [Using python's eval() vs. ast.literal\_eval()?](http://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval) – JuniorCompressor Nov 21 '16 at 12:11
  • 1
    `(2, 2)` is a tuple, do you want a tuple or a list? – Steven Summers Nov 21 '16 at 12:12
  • @StevenSummers The string is of the form in the post. Actually, the final value could be a tuple or a list. I didn't realize I was posting a tuple, sorry. – Jalo Nov 21 '16 at 12:15
  • @pshep123 the string-list always has the '(x1,x2)\n' format, being x1 and x2 integers – Jalo Nov 21 '16 at 12:15
  • @JuniorCompressor in the other post they are comparing eval() vs ast.literal_eval(), while in this post I am asking for a way of getting a value inside a string. Actually, the answer of the other post is valid for me, but the question is not the same. Indeed, I wasn't able to find that question because of its different approach – Jalo Nov 21 '16 at 12:24
  • more precisely is a duplicate of http://stackoverflow.com/questions/4388626/python-safe-eval-string-to-bool-int-float-none-string – JuniorCompressor Nov 21 '16 at 12:27
  • @JuniorCompressor In those posts the answer is valid for me. However, the questions are not explicitly asking a way of getting a list or tuple from a string. Thus, I had no chance of finding them – Jalo Nov 21 '16 at 12:32
  • @Jalo your question was about safe evaluation of a python data type and in order to be classified as duplicate it doesn't need 100% match. In either case, even with a duplicate, you can get the answer you want, either from a new answer or an old one. – JuniorCompressor Nov 21 '16 at 12:35
  • @JuniorCompressor My question was actually answered, thanks to you and the authors of the answers below ;). The point I am trying to explain is that, with the problem I had, I was not able to find those questions (as they have different approaches) and maybe in the future another person has the same problem and finds easier this post – Jalo Nov 21 '16 at 12:38
  • That's why duplicated posts don't get deleted. In order for other people to find them with different keywords. But they are marked duplicates nonetheless in order for anyone to have access to the "original" questions. – JuniorCompressor Nov 21 '16 at 12:40

3 Answers3

4

Use ast module literal_eval method for a safer eval

import ast
formatted_value = ast.literal_eval(value)
Skycc
  • 3,496
  • 1
  • 12
  • 18
1

If you know the input contains a tuple

from ast import literal_eval as make_tuple
make_tuple(value)
blue_note
  • 27,712
  • 9
  • 72
  • 90
0

Well to give the alternative approach you can do.

s = '(2, 2)\n'
s = s.strip()
if s.startswith('(') and s.endswith(')'):
    tup = tuple(int(i) for i in s[1:-1].split(','))
    print(tup)

Or if you want a list

s = '(2, 2)\n'
s = s.strip()
if s.startswith('(') and s.endswith(')'):
    lst = [int(i) for i in s[1:-1].split(',')]
    print(lst)
Steven Summers
  • 5,079
  • 2
  • 20
  • 31