Take the pseudocode below for example:
Python keeps the previous value for x, so if get_sum() fails, the conditional is still checked using the previous value of x.
Is this because python for loop doesn't introduce a new scope and is it ok to simply del the object at the end of each iteration?
for number in number_list:
try:
x = get_sum()
except:
....
if x > 100:
do something
Every variable in python is created in the scope of their respective functions and classes rather than at different levels of indentation, or in for loops or while loops. There's no block scope in python like there is in java.
If you need x to not retain its old value, you can always set x = None in your except clause and have a conditional catch it later on. If i'm misinterpreting your question please leave a comment
Related
for i in rates:
if input_currency == currency:
if output_currency in rates[currency]:
pass
else:
for i in rates:
Is it generally a bad thing to use the same variable i again within a for loop? Even if I loop through the same data structure again? PyCharm just tells me it's been used already, but it still works.
It's not wrong. But it's dangerous if you don't know what you are doing. For example, you might have problems if you want to use i inside the outer loop:
rates = [1,2,3,4,5]
for i in rates:
for i in rates:
pass
print(i) # This always prints 5
This may confuse you if you're not familiar with Python. In C, for example, a variable defined inside the inner loop is different from the one that is defined in the outer loop (i.e., you can reuse the same name for different variables).
In python you can create rather hard to find bugs by giving a loop variable a name that already exists in the rest of your code.
The pattern looks like this:
idx = 0 # the result of some calculations
for idx in range(10):
# do something
# use idx and expect it to be 0
# surprise, idx is actually 9
Of course, the obvious solution is to have better variable names. But even if you use very descriptive names, there is still a chance that the same name seems like a good choice somewhere else in your code.
Especially in numerical code, there are just so many indices that it gets really hard to keep track. And variables pretty much never run out of scope:
for idx in range(10):
# do something
# idx is now in scope
# autocomplete will suggest idx, but it is still fine as a loop variable
for idx in range(10):
# do something
Is it possible to set up a linter for this problem ?
I want to be warned whenever I use a variable as a loop variable that has been defined in an enclosing scope. The rule would need a notion of scopes and their child-scopes. The first code sample above should create a warning. In the second example, the loop variable already exists in the outer scope, but it has been defined in a child of the enclosing scope. That should be fine.
I'm given this dataset and tasked with coming up with a loop to find the highest value in this dictionary. I'm confused with why by placing the print function inside the loop(#1) produces a different answer from placing it outside the loop(#2).
data = {'Jeremy':73284, 'Hansel':8784.3, 'Uee':9480938.2,
'Seolhyun':984958.3, 'Ketsuno Ana':24131, 'Trump':45789}
highest_network = data["Jeremy"]
for key,value in data.items():
if value > highest_network:
highest_network = value
print(key,value) #1
print(key,value) #2
Sorry, I'm still a beginner in python hence I am still not very familiar with some concept.
At any given time during execution, python keeps what's essentially a dictionary of variable names that exist, and their values. The way this interacts with scope is kind of confusing/complicated, but suffice it to say that in this situation, key and value are declared in a scope that is outside their for loop.
Now, note the first print statement. Since it's inside the loop, and the key and value are going to be constantly updating, it will print the current key and value every time it's executed.
The second print statement is outside the loop, and is executed after the loop has run. Keep in mind that the variables key and value are still in scope, and still hold whatever the last things assigned to them are (in this case, key and value will be the last value you'd get from data.items()). This is why they behave differently - because the value of key and value are different every time you try printing them.
Keep in mind that the order in which data.items() puts the data is effectively arbitrary, as far as the standards are concerned. The order in which each key is put through that for loop will be consistent from run to run on your machine, but if you put the same code on someone else's machine it might act differently. As a result, you should not rely on this behavior being consistent.
The first print statement is inside an conditional branch and inside the for loop.
Therefore, every time the condition given by the if statement is True the print function gets executed. Now, given your data, this holds only for the case of "Uee", whose value has the largest value, and also is the first value to be larger than "Jeremy". Also note that the order which items() return does not have to be the same every time so you can get also different results and the first print can be executed many times.
Now, the second print is outside the for loop, which means that the key and value variables hold the last value they were assigned. Again, this could be anything from the dictionary, since the ordering returned by items() does not have to be the same. In case the dictionary is traversed in the order specified in the example, it would print the "trump" entry.
This question already has answers here:
Break out of a while loop using a function
(3 answers)
Closed 7 years ago.
I need to break out of a for loop according to the result obtained after calling a function. This is an example of what I'm after (does not work obviously):
def break_out(i):
# Some condition
if i > 10:
# This does not work.
return break
for i in range(1000):
# Call function
break_out(i)
Of course this is a very simple MWE, my actual function is much bigger which is why I move it outside of the for loop.
This answer says it is not possible and I should make the function return a boolean and add an if statement inside the for loop to decide.
Since it's a rather old question and it didn't get much attention (also, it's applied to while loops), I'd like to re-check if something like this is possible.
No, it's not (reasonably) possible. You could raise an exception, I suppose, but then you'll have to catch it with a try/except statement outside the loop.
Since OP has expressed curiosity about this, I'm going to explain why Python doesn't allow you to do this. Functions are supposed to be composable elements. They're meant to work in different contexts.
Allowing a function to break out of a loop has two separate problems:
Client code might not expect this behavior.
What if there is no loop?
For (1), if I read some code like this:
import foo # some library I didn't write
while condition:
foo.bar()
assert not condition
I reasonably assume the assertion will not fire. But if foo.bar() was able to break out of the loop, it could.
For (2), perhaps I wrote this somewhere else:
if condition:
foo.bar()
It's not clear what that should do if foo.bar() tries to break out of the loop, since there is no loop.
Rather than return break, return a value that forces a break condition. To extend your example:
def break_out(i):
# Some condition
return i > 10 # Returns `True` if you should break from loop.
for i in range(1000):
# Call function
if break_out(i):
break
# Insert the rest of your code here...
I'm currently developing some things in Python and I have a question about variables scope.
This is the code:
a = None
anything = False
if anything:
a = 1
else:
a = 2
print a # prints 2
If I remove the first line (a = None) the code still works as before. However in this case I'd be declaring the variable inside an "if" block, and regarding other languages like Java, that variable would only be visible inside the "if".
How exactly variable scoping works in Python and what's the good way to program in cases like this?
Thanks!
As a rule of thumb, scopes are created in three places:
File-scope - otherwise known as module scope
Class-scope - created inside class blocks
Function-scope - created inside def blocks
(There are a few exceptions to these.)
Assigning to a name reserves it in the scope namespace, marked as unbound until reaching the first assignment. So for a mental model, you are assigning values to names in a scope.
I believe that Python uses function scope for local variables. That is, in any given function, if you assign a value to a local variable, it will be available from that moment onwards within that function until it returns. Therefore, since both branches of your code are guaranteed to assign to a, there is no need to assign None to a initially.
Note that when you can also access variables declared in outer functions -- in other words, Python has closures.
def adder(first):
def add(second):
return first + second
return add
This defines a function called adder. When called with an argument first, it will return a function that adds whatever argument it receives to first and return that value. For instance:
add_two = adder(2)
add_three = adder(3)
add_two(4) # = 6
add_three(4) # = 7
However, although you can read the value from the outer function, you can't change it (unlike in many other languages). For instance, imagine trying to implement an accumulator. You might write code like so:
def accumulator():
total = 0
def add(number):
total += number
return total
return add
Unfortunately, trying to use this code results in an error message:
UnboundLocalError: local variable 'total' referenced before assignment
This is because the line total += number tries to change the value of total, which cannot be done in this way in Python.
There is no problem assigning the variable in the if block.
In this case it is being assigned on both branches, so you can see it will definitely be defined when you come to print it.
If one of the branches did not assign to a then a NameError exception would be raise when you try to print it after that branch
Python doesn't need variables to be declared initially, so you can declare and define at arbitrary points. And yes, the scope is function scope, so it will be visible outside the if.
i'm quite a beginner programmer, but for what i know, in python private variables don't exist. see private variables in the python documentation for a detailed discussion.
useful informations can also be found in the section "scopes and namespaces" on the same page.
personally, i write code like the one you posted pretty much every day, especially when the condition relies in getting input from the user, for example
if len(sys.argv)==2:
f = open(sys.argv[1], 'r')
else:
print ('provide input file')
i do declare variables before using them for structured types, for example i declare an empty list before appending its items within a loop.
hope it helps.