Wednesday, April 20, 2011

Python __str__ and lists

Hello

In Java, if I call List.toString(), it will automatically call the toString() method on each object inside the List. For example, if my list contains objects o1, o2, and o3, list.toString() would look something like this:

"[" + o1.toString() + ", " + o2.toString() + ", " + o3.toString() + "]"

Is there a way to get similar behavior in Python? I implemented a __str__() method in my class, but when I print out a list of objects, using:

print 'my list is %s'%(list)

it looks something like this:

[<__main__.cell instance at 0x2a955e95f0>, <__main__.cell instance at 0x2a955e9638>, <__main__.cell instance at 0x2a955e9680>]

how can I get python to call my __str__ automatically for each element inside the list (or dict for that matter)?

From stackoverflow
  • Calling string on a python list calls the __repr__ method on each element inside. For some items, __str__ and __repr__ are the same. If you want that behavior, do:

    def __str__(self):
        ...
    def __repr__(self):
        return self.__str__()
    
  • You can use a list comprehension to generate a new list with each item str()'d automatically:

    print([str(item) for item in mylist])
    
  • Two easy things you can do, use the map function or use a comprehension.

    But that gets you a list of strings, not a string. So you also have to join the strings together.

    s= ",".join( map( str, myList ) )
    

    or

    s= ",".join( [ str(element) for element in myList ] )
    

    Then you can print this composite string object.

    print 'my list is %s'%( s )
    
  • Something like this?

    a = [1, 2 ,3]
    [str(x) for x in a]
    # ['1', '2', '3']
    
  • Depending on what you want to use that output for, perhaps __repr__ might be more appropriate:

    import unittest
    
    class A(object):
        def __init__(self, val):
            self.val = val
    
        def __repr__(self):
            return repr(self.val)
    
    class Test(unittest.TestCase):
        def testMain(self):
            l = [A('a'), A('b')]
            self.assertEqual(repr(l), "['a', 'b']")
    
    if __name__ == '__main__':
        unittest.main()
    
  • I agree with the previous answer about using list comprehensions to do this, but you could certainly hide that behind a function, if that's what floats your boat.

    def is_list(value):
        if type(value) in (list, tuple): return True
        return False
    
    def list_str(value):
        if not is_list(value): return str(value)
        return [list_str(v) for v in value]
    

    Just for fun, I made list_str() recursively str() everything contained in the list.

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.