12
\$\begingroup\$

I'm trying to apply string.strip() to all the leafs that are strings in a multidimensional collection, but my Python is a bit rusty (to say the least). The following is the best I've come up with, but I suspect there's a much better way to do it.

def strip_spaces( item ):
    if hasattr( item, "__iter__" ):
        if isinstance( item, list ):
            return [strip_spaces( value ) for value in item]
        elif isinstance( item, dict ):
            return dict([(value,strip_spaces(value)) for value in item])
        elif isinstance( item, tuple ):
            return tuple([ strip_spaces( value ) for value in item ])
    elif isinstance( item, str ) or isinstance( item, unicode ):
        item = item.strip()
    return item
\$\endgroup\$

2 Answers 2

6
\$\begingroup\$

I don't understand why you are checking for an __iter__ attribute, as you don't seem to use it. However I would recommend a couple of changes:

  • Use Abstract Base Classes in the collections module to test duck types, such as "Iterable"
  • Use types.StringTypes to detect string types

.

import collections
import types

def strip_spaces( item ):
    if isinstance( item, types.StringTypes ):
        return item.strip()

    if isinstance( item, collections.Iterable ):
        if isinstance( item, list ):
            return [ strip_spaces( value ) for value in item ]

        elif isinstance( item, dict ):
            return dict([ ((strip_spaces(key), strip_spaces(value)) \
                                    for key, value in item.iteritems() ])

        elif isinstance( item, tuple ):
            return tuple( [ strip_spaces( value ) for value in item ] )

    return item
\$\endgroup\$
5
\$\begingroup\$
elif isinstance( item, dict ):
    return dict([(value,strip_spaces(value)) for value in item])

This will transform { ' a ': ' b ' } into {' a ': 'a' }, which I suspect is not what you want. How about:

    return dict([(key, strip_spaces(value)) for key, value in item.items()])
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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