[Tutor] pass tuples to user defined function(beginner)

Steven D'Aprano steve at pearwood.info
Tue Nov 29 13:08:13 CET 2011

bob gailer wrote:
> On 11/28/2011 12:47 PM, James Reynolds wrote:
>> On Mon, Nov 28, 2011 at 12:32 PM, Mayo Adams <mayoadams at gmail.com 
>> <mailto:mayoadams at gmail.com>> wrote:
>>     I am trying to pass a set of tuple strings from a file to a 
>> function I
>>     have defined.  Each tuple is on a separate line, and looks something
>>     like this:
>>      ('note',2048)
> As already pointed out - this is a string (a representation of a tuple), 
> not a tuple.
> Your code must parse the string to extract the string representations of 
> the values, then convert as needed to the desired Python values.
> Tasks like this are not trivial.

In general, parsing can be a hard problem. In this case though, it is easy to 
solve 95% of the problem with a hand-built converter, which may be good enough.

def strto2tuple(s):
     """Convert a string like "('abc', 42)" to a tuple with two items."""
     # Ignore leading and trailing whitespace.
     s = s.strip()
     # Check for round brackets (parentheses), and remove them.
     if s[0] != '(' or s[-1] != ')':
         raise ValueError('malformed string, missing ( or )')
     s = s[1:-1]
     # Split the string into exactly two pieces.
     # FIXME this assumes that the first item contains no commas.
     items = s.split(',')
     n = len(items)
     if n != 2:
         raise ValueError('expected exactly two items but found %d' % n)
     a, b = items
     # Ignore spaces around each item, e.g. ( 'abc' , 42 ) => ('abc', 42)
     a = a.strip()
     b = b.strip()
     # Make sure that the first item looks like a string.
     quotes = '"\''  # FIXME no support for triple quotes yet, or raw strings.
     assert len(quotes) == 2
     for q in quotes:
         if a.startswith(q) and a.endswith(q):
             # Don't include the delimiter quotes in the string.
             a = a[1:-1]
         # This executes if we don't hit a break in the for loop.
         raise ValueError('mismatched or missing quotes')
     assert isinstance(a, str)
     # Make sure the second item is an integer.
     b = int(b, 0)  # Support hex and octal formats too.
     return (a, b)  # And return a real tuple.

This untested function will convert strings in a file like these:

(  'fe', 1)
(  'fi' ,2 )
( "fum"    ,   4  )

into proper tuples with a string and a number. Notice that we allow the user 
to be sloppy with spaces, but we are strict about quotation marks and brackets.

Our converter function is both a little too strict (e.g. it forbids the user 
from including triple-quoted strings) and a little too lax (e.g. it allows 
malformed strings like ''abc'). You might not care about these weaknesses. If 
you do, you need to move up to a real parser, which is significantly more complex.


More information about the Tutor mailing list