str is to return a printable form of the object only! From the docs
str(object)does not always attempt to return a string that is acceptable to
eval(); its goal is to return a printable string.
__str__ function in a class is called whenever you call the
str on an object. Again from the documentation
Called by the
str()built-in function and by the
list is to create a list from an iterable! Again from the docs
listwhose items are the same and in the same order as iterable‘s items
str(list) gives you a printable form and
list(str(list)) will iterate over the string. That is
list(str(list)) will give you a list of the individual characters of the printable form of the argument passed.
A small walk-through between the nested calls,
l = ['a','b']
When you call
str(l), it returns a printable form of the list
l, that is
Now you can see clearly that
"['a','b']" is a string and is indeed an iterable. Now when you call
list on this i.e.
list("['a','b']") you get a weird list like
['[', "'", 'a', "'", ',', "'", 'b', "'", ']']. Why does this happen? This happens because the string iterates over its characters, you can test this by using a dummy string,
>>> 'dummy' 'dummy' >>> list('dummy') ['d', 'u', 'm', 'm', 'y']
Thus when you call the
list on a string you get a list of character. Note that again here, when you call
list('dummy'), you will not get back your original string
'dummy', so again you will have to use
join! Thus recalling the same function will NOT get you back your original object!
str over a list calls the builtin
__str__ method of the list?
The answer is NO!
What happens internally when you call
str on a list?
Whenever you call
str on an list object, the steps followed are
- Call the
reprof each of the list element.
- Add a fancy
[at the front and another
]at the end of the list.
- Join all of them with a comma.
/* Do repr() on each element. Note that this may mutate the list, so must refetch the list size on each iteration. */ line (382) /* Add "" decorations to the first and last items. */ line (398) /* Paste them all together with ", " between. */ line (418)
These correspond to the points I mentioned above.
Now what is
repr prints the string representation of all the objects. Again from the documentation
Return a string containing a printable representation of an object.
and also note this sentence!
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to
eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object.
list(str(list)) turn the
str(list) back to the original list?
str(list) actually creates the
repr representation of the list object. So to get back the list after calling
str on the list, you actually need to do
eval on it and not a
Safely evaluate an expression node or a string containing a Python literal or container display
2. Using string functions and builtins
Another workaround can be done using
>>> x = ['abc', 'def', 'ghi'] >>> a = str(x) >>> a[2:-2].split("', '") ['abc', 'def', 'ghi']
This is just a simple way to do that for a list of strings. For a list of integers you will need
>>> x = [1,2,3] >>> a =str(x) >>> list(map(int,a[1:-1].split(', '))) # No need for list call in Py2 [1, 2, 3]
literal_eval these are simple hacks given that you know the elements of the list. If they are heterogeneous in nature like
[1, "a", True] then you will have to loop through the split list and discover the element type and then convert it and append the converted element to a final list.