views:

384

answers:

4

Hi,

I need to convert a list (or a dict) into a comma-separated list for passing to another language.

Is there a nicer way of doing this than:

 result = ''
 args = ['a', 'b', 'c', 'd']

 i = 0
 for arg in args:
     if i != 0:    result += arg
     else:         result += arg + ', '
     i += 1

 result = 'function (' + result + ')

Thanks, Dan

+12  A: 

', '.join(args) will do the trick.

unbeknown
And if the args aren't all strings, ', '.join( map(str,args) ) will work nicely.
S.Lott
Or ', '.join(str(x) for x in args)
James Hopkin
Thanks S. and James for the extra comment on this StackOverflow post. This is just what I needed.
Chris
+10  A: 
'function(%s)' % ', '.join(args)

produces

'function(a, b, c, d)'
James Hopkin
+1 for doing format instead of concatenation.
S.Lott
with Python 3.0'function ({0})'.format(', '.join(args))
Mapad
A: 

Why not use a standard that both languages can parse, like JSON, XML, or YAML? simplejson is handy, and included as json in python 2.6.

Nick Retallack
A: 
result = 'function (%s)' % ', '.join(map(str,args))

I recommend the map(str, args) instead of just args because some of your arguments could potentially not be strings and would cause a TypeError, for example, with an int argument in your list:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, int found

When you get into dict objects you will probably want to comma-separate the values of the dict (presumably because the values are what you want to pass into this function). If you do the join method on the dict object itself, you will get the keys separated, like so:

>>> d = {'d':5, 'f':6.0, 'r':"BOB"}
>>> ','.join(d)
'r,d,f'

What you want is the following:

>>> d = {'d':5, 'f':6.0, 'r':"BOB"}
>>> result = 'function (%s)' % ', '.join(map(str, d.values()))
>>> result
'function (BOB, 5, 6.0)'

Note the new problem you encounter, however. When you pass a string argument through the join function, it loses its quoting. So if you planned to pass strings through, you have lost the quotes that usually would surround the string when passed into a function (strings are quoted in many general-purpose languages). If you're only passing numbers, however, this isn't a problem for you.

There is probably a nicer way of solving the problem I just described, but here's one method that could work for you.

>>> l = list()
>>> for val in d.values():
...   try:
...     v = float(val) #half-decent way of checking if something is an int, float, boolean
...     l.append(val) #if it was, then append the original type to the list
...   except:
...     #wasn't a number, assume it's a string and surround with quotes
...     l.append("\"" + val + "\"")
...
>>> result = 'function (%s)' % ', '.join(map(str, l))
>>> result
'function ("BOB", 5, 6.0)'

Now the string has quotes surrounding itself. If you are passing more complex types than numeric primitives and strings then you probably need a new question :)

One last note: I have been using d.values() to show how to extract the values from a dictionary, but in fact that will return the values from the dictionary in pretty much arbitrary order. Since your function most likely requires the arguments in a particular order, you should manually construct your list of values instead of calling d.values().

Chris Cameron
The best way to check if val is a string is isinstance(val, basestring) (or just isinstance(val, str) in Python3.0)
James Hopkin
Is isinstance in Python 2.5.2? I can't upgrade to 2.6 or 3.0 because our company depends on so many third-party packages that are only compiled to 2.5.2 or earlier. Also, someone once told me that using isinstance can force something to become the checked instance even if it wasn't. Is that true?
Chris Cameron