Scope of next() in Python - python

I am trying to use the next function on an iterator, however, I have a local variable in the same scope that is also named next. The obvious solution is to rename the local variable, however, I'm fairly new to Python so I'm curious to learn how to prefix the next function so I achieve the desired behavior.
The code I'm using looks something like this:
for prev, curr, next in neighborhood(list):
if (prev == desired_value):
print(prev+" "+next)
desired_value = next(value_iterator)
Note that I'm using Python 3.2.

You can use __builtins__.next to refer to the next built-in function.
for prev, curr, next in neighborhood(list):
if (prev == desired_value):
print(prev+" "+next)
desired_value = __builtins__.next(value_iterator)
However, as you point out, the obvious solution is to use a different name for your variable.

You can call the next() method of the iterator directly. You lose, however, the ability to suppress StopIteration at the end of the iteration in favor of seeing a default value.
desired_value = value_iterator.next()
Note that in Python 3, this method has been renamed __next__().

Before you assign something to next, use something like:
real_next = next

Related

A new way to keep track of global variables inside a recursive function in Python?

So I came across a recursive solution to a problem that keeps track of a global variable differently than I've seen before. I am aware of two ways:
One being by using the global keyword:
count = 0
def global_rec(counter):
global count
count += 1
# do stuff
print(count)
And another using default variables:
def variable_recursive(counter, count=0):
count += 1
if counter <= 0:
return count
return variable_recursive(counter-1, count)
The new way:
#driver function
def driver(counter):
#recursive function being called here
rec_utility.result = 0 <---initializing
rec_utility(counter) <--- calling the recursive function
print(rec_utility.result)
def rec_utility(counter):
if counter <= 0:
return
rec_utility.result += 1 <---- 'what is happening here'
rec_utility(counter-1)
I find this way a lot simpler, as in default variable method we have to return the variables we want to keep a track of and the code get really messy really fast. Can someone please explain why passing a variable joint to a function, like an object property works? I understand that python functions are nothing but objects, but is this a hacky way of keeping track of the variables or is it common practice? If so why do we have so many ways to achieve the same task? Thanks!
This isn't as magical as you might think. It might be poor practice.
rec_utility is just a variable in your namespace which happens to be a function. dir() will show it listed when it is in scope. As an object it can have new fields set. dir(rec_utility) will show these new fields, along with __code__ and others.
Like any object, you can set a new field value, as you are doing in your code. There is only one rec_utility function, even though you call it recursively, so its the same field when you initialize it and when you modify it.
Once you understand it, you can decide if it is a good idea. It might be less confusing or error prone to use a parameter.
In some sense, this question has nothing to do with recursive functions. Suppose a function requires an item of information to operate correctly, then do you:
provide it via a global; or
pass it in as a parameter; or
set it as a function attribute prior to calling it.
In the final case, it’s worth considering that it is not entirely robust:
def f():
# f is not this function!!
return f.x + 1
f.x = 100
for f in range(10): pass
Generally, we would consider the second option the best one. There’s nothing special really about its recursive nature, other than the need to provide state, which is information, to the next invocation.

Running function code only when NOT assigning output to variable?

I am looking for a way in python to stop certain parts of the code inside a function but only when the output of the function is assigned to a variable. If the the function is run without any assignment then it should run all the inside of it.
Something like this:
def function():
print('a')
return ('a')
function()
A=function()
The first time that I call function() it should display a on the screen, while the second time nothing should print and only store value returned into A.
I have not tried anything since I am kind of new to Python, but I was imagining it would be something like the if __name__=='__main__': way of checking if a script is being used as a module or run directly.
I don't think such a behavior could be achieved in python, because within the scope of the function call, there is no indication what your will do with the returned value.
You will have to give an argument to the function that tells it to skip/stop with a default value to ease the call.
def call_and_skip(skip_instructions=False):
if not skip_instructions:
call_stuff_or_not()
call_everytime()
call_and_skip()
# will not skip inside instruction
a_variable = call_and_skip(skip_instructions=True)
# will skip inside instructions
As already mentionned in comments, what you're asking for is not technically possible - a function has (and cannot have) any knowledge of what the calling code will do with the return value.
For a simple case like your example snippet, the obvious solution is to just remove the print call from within the function and leave it out to the caller, ie:
def fun():
return 'a'
print(fun())
Now I assume your real code is a bit more complex than this so such a simple solution would not work. If that's the case, the solution is to split the original function into many distinct one and let the caller choose which part it wants to call. If you have a complex state (local variables) that need to be shared between the different parts, you can wrap the whole thing into a class, turning the sub functions into methods and storing those variables as instance attributes.

Is it a bad programing practice to put a function inside a class method?

I'm looking at a case like this:
def parse_item(self, response):
item = MetrocItem()
def ver(string):
if string:
return string
else:
return 'null'
item['latitude'] = ver(response.xpath('//input[#id="latitude"]/#value').extract_first())
It works, but is there a better way to do this?
As #Graipher mentioned in the comments, this is certainly valid in some cases, but in your particular case, it is unnecessary. If your function depends on a local variable, then you're returning a closure that needs to be reconstructed every time you call the method. But in your case, the function is going to behave the same way every time you call the method, so it would make more sense to define it globally as a private method, or even as a lambda in your case.
ver = lambda x: x if x else 'null'
But the preferred approach would be to simply define it globally and start the name with an underscore to make the intention clear.
def _ver(string):
...
You can get rid of that function completely:
string = response.xpath('//input[#id="latitude"]/#value').extract_first()
item['latitude'] = string if string else 'null'
There are use cases for having a local function - either in a class method or other method, say if you want a closure capturing something local.
In you case you want something like a colasecing null:
e.g.
>>> s = None
>>> s or "None"
'None'
So, you can use
item['latitude'] = response.xpath('//input[#id="latitude"]#value').extract_first() or "null"
It is not bad practice, but here's an alternative.
Since this small function doesn't depend on anything in parse_item and you might want it to be constructed only once, for performance, you could do this:
def parse_item(self, response):
...
def _ver(string):
...
parse_item.ver = _ver
del _ver
and refer to it inside parse_item as parse_item.ver instead of just ver. This avoids cluttering the global namespace, even with an underscored method that Python partially hides for you.
I would have recommended the lambda expression as another alternative, but Silvio got to it first.
Also, the comments that it could be a global function, visible to all, only makes sense if there's any chance it might be used anywhere else.
Also also, you can eliminate this example completely, as doctorlove and Niklas have suggested, but I assume that you mean this as an example of more complex cases.
I guess parse_item is a method inside your class. Then you can use Python's "private" methods to make your code more readable and cleaner.
Check how to write Python "private" method and then check why it's not actually a private method. ;)

python: function that will call itself

i was wondering if i can get your help with the stucture.logic of a function that will need to call itself
def populate_frequency5(d,data,total_compare):
freq=[]
prev = None
for row in d:
if prev is None or prev==row[11]:
freq.append(row[16])
doctor=row[10]
drug=row[11][:row[11].find(' ')].capitalize()
else:
make_image_url_doctor(freq,doctor,drug,data)
total_compare=True
del freq[:]
prev=row[11]
if total_compare:
(b1,bla,bla1)=medications_subset2(data,[drug.upper()])
data1=calculate_creat_conc4(b1)
populate_frequency5(data1,['a'],total_compare=True)
total_compare=False
the first time the function is called i need it to run this:
def populate_frequency5(d,data,total_compare):
freq=[]
prev = None
for row in d:
if prev is None or prev==row[11]:
freq.append(row[16])
doctor=row[10]
drug=row[11][:row[11].find(' ')].capitalize()
else:
make_image_url_doctor(freq,doctor,drug,data)
(b1,bla,bla1)=medications_subset2(data,[drug.upper()])
data1=calculate_creat_conc4(b1)
del freq[:]
prev=row[11]
then somehow the second time when i call it, i need it to run this way:
def populate_frequency5(d,data,total_compare):
freq=[]
prev = None
for row in d:
if prev is None or prev==row[11]:
freq.append(row[16])
doctor=row[10]
drug=row[11][:row[11].find(' ')].capitalize()
run_another_function()
Your current logic is faulty and will lead to runaway recursion. If you ever make a recursive call, you'll pass it a total_compare of True; but then within that recursive call it will not be set to False again, so when checked it will be true and yet another recursive call (with the same defect) will inevitably result.
The setting of total_compare in the calling instance (were it ever to execute, which it won't because of the runaway recursion) is irrelevant: it's the last statement ever executed there and it's setting a local variable, so of course it can be removed without any observable effects. Maybe you don't realize that each instance of a function in recursive calls has its own set of local variables (including arguments -- they're also local variables, just ones that get initializer by the caller), which is why I'm pointing this out explicitly.
Your examples "desired code" 1 and 2 don't really help because they never show the function calling itself. Under what conditions, exactly, does the function need to call itself recursively (a) if it was called non-recursively, (b) if it was already called recursively? Remember that, to avoid runaway recursion, there must be eventually reached a "base case" where no further recursion occurs.
Given that in your first ("runaway recursion") example the recursive call appears to be the last action of the caller (net of the useless and therefore removable setting of the total_compare local variable), I should also point out that such "tail recursion" can easily be turned into iteration (and, in Python, that's usually advisable, since Python does not optimize tail recursion as other languages do).

Is it possible only to declare a variable without assigning any value in Python?

Is it possible to declare a variable in Python, like so?:
var
so that it initialized to None? It seems like Python allows this, but as soon as you access it, it crashes. Is this possible? If not, why?
EDIT: I want to do this for cases like this:
value
for index in sequence:
if value == None and conditionMet:
value = index
break
Related Questions
Why can a function modify some arguments as perceived by the caller, but not others?
Python Variable Declaration
See Also
Python Names and Values
Other languages have "variables"
Why not just do this:
var = None
Python is dynamic, so you don't need to declare things; they exist automatically in the first scope where they're assigned. So, all you need is a regular old assignment statement as above.
This is nice, because you'll never end up with an uninitialized variable. But be careful -- this doesn't mean that you won't end up with incorrectly initialized variables. If you init something to None, make sure that's what you really want, and assign something more meaningful if you can.
In Python 3.6+ you could use Variable Annotations for this:
https://www.python.org/dev/peps/pep-0526/#abstract
PEP 484 introduced type hints, a.k.a. type annotations. While its main focus was function annotations, it also introduced the notion of type comments to annotate variables:
# 'captain' is a string (Note: initial value is a problem)
captain = ... # type: str
PEP 526 aims at adding syntax to Python for annotating the types of variables (including class variables and instance variables), instead of expressing them through comments:
captain: str # Note: no initial value!
It seems to be more directly in line with what you were asking "Is it possible only to declare a variable without assigning any value in Python?"
Note: The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.
I'd heartily recommend that you read Other languages have "variables" (I added it as a related link) – in two minutes you'll know that Python has "names", not "variables".
val = None
# ...
if val is None:
val = any_object
I'm not sure what you're trying to do. Python is a very dynamic language; you don't usually need to declare variables until you're actually going to assign to or use them. I think what you want to do is just
foo = None
which will assign the value None to the variable foo.
EDIT: What you really seem to want to do is just this:
#note how I don't do *anything* with value here
#we can just start using it right inside the loop
for index in sequence:
if conditionMet:
value = index
break
try:
doSomething(value)
except NameError:
print "Didn't find anything"
It's a little difficult to tell if that's really the right style to use from such a short code example, but it is a more "Pythonic" way to work.
EDIT: below is comment by JFS (posted here to show the code)
Unrelated to the OP's question but the above code can be rewritten as:
for item in sequence:
if some_condition(item):
found = True
break
else: # no break or len(sequence) == 0
found = False
if found:
do_something(item)
NOTE: if some_condition() raises an exception then found is unbound.
NOTE: if len(sequence) == 0 then item is unbound.
The above code is not advisable. Its purpose is to illustrate how local variables work, namely whether "variable" is "defined" could be determined only at runtime in this case.
Preferable way:
for item in sequence:
if some_condition(item):
do_something(item)
break
Or
found = False
for item in sequence:
if some_condition(item):
found = True
break
if found:
do_something(item)
Well, if you want to check if a variable is defined or not then why not check if its in the locals() or globals() arrays? Your code rewritten:
for index in sequence:
if 'value' not in globals() and conditionMet:
value = index
break
If it's a local variable you are looking for then replace globals() with locals().
I usually initialize the variable to something that denotes the type like
var = ""
or
var = 0
If it is going to be an object then don't initialize it until you instantiate it:
var = Var()
First of all, my response to the question you've originally asked
Q: How do I discover if a variable is defined at a point in my code?
A: Read up in the source file until you see a line where that variable is defined.
But further, you've given a code example that there are various permutations of that are quite pythonic. You're after a way to scan a sequence for elements that match a condition, so here are some solutions:
def findFirstMatch(sequence):
for value in sequence:
if matchCondition(value):
return value
raise LookupError("Could not find match in sequence")
Clearly in this example you could replace the raise with a return None depending on what you wanted to achieve.
If you wanted everything that matched the condition you could do this:
def findAllMatches(sequence):
matches = []
for value in sequence:
if matchCondition(value):
matches.append(value)
return matches
There is another way of doing this with yield that I won't bother showing you, because it's quite complicated in the way that it works.
Further, there is a one line way of achieving this:
all_matches = [value for value in sequence if matchCondition(value)]
If I'm understanding your example right, you don't need to refer to 'value' in the if statement anyway. You're breaking out of the loop as soon as it could be set to anything.
value = None
for index in sequence:
doSomethingHere
if conditionMet:
value = index
break
I know it's coming late but with python3, you can declare an uninitialized value by using
uninitialized_value:str
# some code logic
uninitialized_value = "Value"
But be very careful with this trick tho, because
uninitialized_value:str
# some code logic
# WILL NOT WORK
uninitialized_value += "Extra value\n"
If None is a valid data value then you need to the variable another way. You could use:
var = object()
This sentinel is suggested by Nick Coghlan.
Is it possible to declare a variable in Python (var=None):
def decl_var(var=None):
if var is None:
var = []
var.append(1)
return var
You look like you're trying to write C in Python. If you want to find something in a sequence, Python has builtin functions to do that, like
value = sequence.index(blarg)
var_str = str()
var_int = int()
You can trick an interpreter with this ugly oneliner if None: var = None
It do nothing else but adding a variable var to local variable dictionary, not initializing it. Interpreter will throw the UnboundLocalError exception if you try to use this variable in a function afterwards. This would works for very ancient python versions too. Not simple, nor beautiful, but don't expect much from python.

Categories