Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the value of the last assigned variable in iPython?

Tags:

python

ipython

I am a total iPython newbie, but I was wondering if there is a way to get the value of the last assigned variable:

In [1]: long_variable_name = 333
In [2]: <some command/shortcut that returns 333>

In R we have .Last.value:

> long_variable_name = 333
> .Last.value
[1] 333
like image 759
nachocab Avatar asked Oct 25 '13 14:10

nachocab


People also ask

How do I get the previous value of a variable in Python?

There is no way to know the previous value of a variable without assigning to the object another variable. Only the presence of references keeps an object alive in memory. The garbage collector disposes of the object, when the reference count of the object reaches zero.

What is the command to print the final result of IPython?

IPython allows you to go beyond the single underscore _ with double ( __ ) and triple underscore ( ___ ), returning results of the second- and third-to-last commands.

How do you view the value of a variable in Python?

Python variables store values in a program. You can refer to the name of a variable to access its value. The value of a variable can be changed throughout your program. Variables are declared using this syntax: name = value.


2 Answers

There's a shortcut for the last returned object, _.

In [1]: 1 + 3
Out[1]: 4

In [2]: _
Out[2]: 4
like image 119
TankorSmash Avatar answered Sep 18 '22 21:09

TankorSmash


You can use IPython's In and Out variables which contain the commands/statements entered and the the corresponding output (if any) of those statements.

So, a naive approach would be to use those variables as the basis of defining a %last magic method.

However, since not all statements necessarily generate output, In and Out are not synchronous.

So, the approach I came up with was to parse In, and look for the occurrences of = and parse those lines for the output:

def last_assignment_value(self, parameter_s=''):
     ops = set('()')
     has_assign = [i for i,inpt in enumerate(In) if '=' in inpt] #find all line indices that have `=`
     has_assign.sort(reverse=True) #reverse sort, because the most recent assign will be at the end
     for idx in has_assign:
         inpt_line_tokens = [token for token in In[idx].split(' ') if token.strip() != ''] #
         indices = [inpt_line_tokens.index(token) for token in inpt_line_tokens if '=' in token and not any((c in ops) for c in token)]
         #Since assignment is an operator that occurs in the middle of two terms
         #a valid assignment occurs at index 1 (the 2nd term)
         if 1 in indices:
             return ' '.join(inpt_line_tokens[2:]) #this simply returns on the first match with the above criteria

And, lastly to make that your own custom command in IPython:

get_ipython().define_magic('last', last_assignment_value)

And, now you can call:

%last

And this will output the term assigned as a string (which may not be what you want).

However, there is a caveat to this: in that if you had entered incorrect input that involved assignment; e.g.: (a = 2), this method will pick it up. And, if your assignment involved variables: e.g. a = name, this method will return name and the not the value of name.

Given that limitation, you can then use the parser module to try and evaluate the expression like this (which can be appended to last_assignment_value in the last if statement):

import parser
def eval_expression(src):
    try:
        st = parser.expr(src)
        code = st.compile('obj.py')
        return eval(code)
    except SyntaxError:
        print 'Warning: there is a Syntax Error with the RHS of the last assignment! "%s"' % src
        return None

However, given the possible evils of eval, I've left that inclusion up to you.

But, to be perfectly honest, a truly wholesome method would involve a parsing of the statement to verify the validity of the found input, as well as the input before it and more.

REFERENCES: https://gist.github.com/fperez/2396341

like image 23
jrd1 Avatar answered Sep 17 '22 21:09

jrd1