1

I'm using the Python ast module to obtain a list of variable names in a Python expression. For example, the expression [int(s[i:i + 3], 2) for i in range(0, len(s), 3)] should return a singleton list with the variable name s like [s]. I've tried the following code snippet -

names = [
    node.id for node in ast.walk(ast.parse(formula)) 
    if isinstance(node, ast.Name)
]

which returns a list of variables plus function names in the ast -

['int', 'i', 's', 'range', 'i', 'len', 's', 'i']

But I don't want to include function names like range, len, int and the iterator i.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 1
    How would the AST know whether a variable points to a function or not? Do you want to exclude the nodes that are part of a call? Why don't you consider ``i`` to be a variable? Are you specifically looking for free/unbound names, i.e. those looked up from outside the expression? – MisterMiyagi Jul 15 '21 at 08:28
  • All the `identifiers` are just variable names to the syntactic parser. E.g. `int`, `isinstance` or `range` can just as easily be bound to objects other that the built-ins they ususally refer to. You would have to gather extra information from the `locals` and `globals` context in which the formula would be evaluated. – user2390182 Jul 15 '21 at 08:29
  • Yes I want to exclude nodes part of a call and those generated during iteration. – Shraddha_96 Jul 15 '21 at 08:56
  • What about nodes in assignment expressions? What about parameters of ``lambda``s? – MisterMiyagi Jul 15 '21 at 09:06
  • In the expression `sum(map(lambda x: x * x, l))`, I want to include `l` but not include `x`. In case of assignment expressions, exclude the lhs node. – Shraddha_96 Jul 15 '21 at 13:46

1 Answers1

-1

You can use similar approach but then filter out names from builtins. Something like this

import ast
import builtins

def get_variables(expression):
    tree = ast.parse(expression)
    variables = []
    for node in ast.walk(tree):
        if isinstance(node, ast.Name):
            variables.append(node.id)
    return tuple(v for v in set(variables) if v not in vars(builtins))