Leahcim Leahcim - 3 months ago 22
Python Question

How to convert tuple to a list

Following one of the accepted solutions to this SO question, I tried to convert a tuple into a list by doing this

mylist = list(mytuple)


However, I am getting a
Tuple object is not iterable
error. Is there a way to convert a tuple into a list?

Note, not that it really matters for this question, the tuple in question is a
Tuple
of
ast
objects, one being type
ast.Str
, the other being
ast.Name
. My ultimate goal is to create a string of the two. However, there might be situations where there are more than two elements in the tuple so I need to be able to iterate over the tuple to check what type of
ast
object each element is.

This is the error message from the python interpreter

TypeError: 'Tuple' object is not iterable


This is the code that produced the error

if type(foo) is ast.Tuple:
g = list(foo)

Answer

You don't have a tuple. You have an ast.Node subclass. This does matter, AST nodes represent a parse tree, and although ast.Tuple may, in running Python code, result in a tuple() instance, there the relationship ends. A parse tree is an intermediary stage between source code and bytecode, and only executed bytecode produces actual tuples.

AST node classes only have the attributes documented in the ast module documentation and are not iterable. You can access the _fields, lineno and col_offset attributes, where _fields is an iterable.

For a specific ast.Node subclass, consult the Abstract Grammar section to see what other types of nodes are passed in for that node, and by what names those other objects can be accessed. For ast.Tuple that grammar is:

Tuple(expr* elts, expr_context ctx)

so elts and ctx will be available as two attributes, and elts is a sequence as well. Incidentally, the ast.Node._fields attribute names those attributes as well.

If you are looking for the 'contents' of a tuple as parsed into the tree, look no further than elts; this is already a list:

>>> import ast
>>> tree = ast.parse('("foo", bar)')
>>> tree.body[0].value
<_ast.Tuple object at 0x10262f990>
>>> tree.body[0].value._fields
('elts', 'ctx')
>>> tree.body[0].value.elts
[<_ast.Str object at 0x10262f910>, <_ast.Name object at 0x10262f6d0>]