8
\$\begingroup\$

I code this function to convert list of dict to a specific string to export last in a row table string field.

#!/usr/bin/env python
# encoding: utf-8
from __future__ import unicode_literals, print_function
import types
import collections
from collections import Iterable

def convert_to_string(input):
    if isinstance(input, dict):
        return "{{{}}}".format(",".join(list("{}:{}".format(convert_to_string(key), convert_to_string(value)) for key, value in input.iteritems())))
    elif isinstance(input, list, tuple):
        return "[{}]".format(",".join(list(convert_to_string(element) for element in input)))
    elif isinstance(input, types.StringTypes):
        if isinstance(input, types.UnicodeType):
            return input
        if isinstance(input, types.StringType):
            return input.encode("utf8")
    elif isinstance(input, types.NoneType):
        return ""
    elif isinstance(input, (types.IntType, types.LongType, types.FloatType)):
        return "{}".format(input)
    else:
        try:
            return "{}".format(input)
        except:
            return "<Undefined>"

data = [[{"1": "pomme", "2": "poiré"}, u"pétrole"], [None, 4], [5.00, 6], 7, Iterable]
print (convert_to_string(data))

That return: in IPython

convert_to_string(data)
Out[18]: u"[[{1:pomme,2:poir\xe9},p\xe9trole],[,4],[5.0,6],7,<class '_abcoll.Iterable'>]"
print(convert_to_string(data))
[[{1:pomme,2:poiré},pétrole],[,4],[5.0,6],7,<class '_abcoll.Iterable'>]

Function work fine but do you know more efficient solution to do that?

\$\endgroup\$
  • \$\begingroup\$ Should the output format be strictly as you've shown, or you are allowed to vary/change it? \$\endgroup\$ – alecxe Mar 20 '17 at 16:02
  • \$\begingroup\$ @alecxe What do you think about format "\r\n" in place of ","? \$\endgroup\$ – GeoStoneMarten Mar 20 '17 at 16:07
  • \$\begingroup\$ @alecxe I think the output can add replacement parameters for separator, dict and list delimiter, without enclosing... But final return is that I want actually. POO can be a response to optimisation or factorisation with map and seconde function. \$\endgroup\$ – GeoStoneMarten Mar 20 '17 at 21:46
  • \$\begingroup\$ Thanks. I was initially thinking about using json.dumps() (and may be custom encoders), but was not happy with the result and decided not to post. \$\endgroup\$ – alecxe Mar 20 '17 at 21:57
  • \$\begingroup\$ @alecxe are you talking about json.dumps(data, cls=ComplexEncoder) ? \$\endgroup\$ – GeoStoneMarten Mar 20 '17 at 22:46
1
\$\begingroup\$

I fail to see if the code actually worked, because the isinstance should raise an exception:

    elif isinstance(input, list, tuple):
TypeError: isinstance expected 2 arguments, got 3

The second argument should be a tuple of types:

    elif isinstance(input, (list, tuple)):

but that might be a simply copy-over error.


In your code you do not need to force conversion to a list. The .join function can take an iterator as its argument. You free up a little memory for your program execution.

if isinstance(input, dict):
    return "{{{}}}".format(",".join(("{}:{}".format(convert_to_string(key), convert_to_string(value)) for key, value in input.iteritems())))
elif isinstance(input, list, tuple):
    return "[{}]".format(",".join((convert_to_string(element) for element in input)))

Since you already have imported the types module, I'd suggest that you be consistent, and use types.ListType, types.DictType etc. as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.