I am very new to python and programming. I am learning about loops right now, and tried the following code to see what would happen. What I would like to know is why the following code does not crash or keep repeating "Robert".
Thank you.
name = ["Robert", "Mike", "Garry", "Alex"]
for y in name:
print(y)
del y
print("END")
Each iteration of the for loop creates a "new" y. By deleting this y each time, you are simply deleting the y that belongs to that iteration. It is "recreated" again at the start of the next iteration.
The del won't change the result of this code at all.
The code works because after you delete the name y, you create it again in the next iteration of the loop.
If you try to print y after the loop, you'll see that it won't work with the del statement in.
Related
not working while-loop
i=0
l1=["rohan","sachin","sam","raj"]
while i<len(l1):
if l1[i].startswith('s'): #if i comment out this line it is working
print("GREET "+l1[i])
i=i+1
That is because incrementing of i is done inside if condition instead of while loop. As first word in your list did not start with "S" it wont go inside if hence i is not incremented and while loop executes forever. it is just a logic issue
Indentation is important in Python.
You must increment your counter i every time, not just when you print, otherwise it's an endless loop.
i=0
l1=["rohan","sachin","sam","raj"]
while i<len(l1):
if l1[i].startswith('s'):
print("GREET "+l1[i])
i=i+1 # <- increment counter outside of if-block!
yes ,after shifting counter to left it is working. counter should be placed out side of if block.
I was experimenting with various ways of creating an infinite loop in Python (other than the usual while True), and came up with this idea:
x = {0: None}
for i in x:
del x[i]
x[i+1] = None # Value doesn't matter, so I set it to None
print(i)
On paper, I traced out the way this would infinitely loop:
I loop through the key's value in the dictionary
I delete that entry.
The current counter position in the loop + 1 will be the new key with value None which updates the dictionary.
I output the current counter.
This, in my head, should output the natural numbers in a sort of infinite loop fashion:
0
1
2
3
4
5
.
.
.
I thought this idea was clever, however when I run it on Python 3.6, it outputs:
0
1
2
3
4
Yes, it somehow stopped after 5 iterations. Clearly, there is no base condition or sentinel value in the code block of the loop, so why is Python only running this code 5 times?
There is no guarantee that you will iterate over all your dict entries if you mutate it in your loop. From the docs:
Iterating views while adding or deleting entries in the dictionary may
raise a RuntimeError or fail to iterate over all entries.
You could create an "enumerated" infinite loop similar to your initial attempt using itertools.count(). For example:
from itertools import count
for i in count():
print(i)
# don't run this without some mechanism to break the loop, i.e.
# if i == 10:
# break
# OUTPUT
# 0
# 1
# 2
# ...and so on
In this case, like #benvc wrote, this is not guaranteed to work. But in case you wonder why does it work in C-Python:
The C-Python implementation destroys the dict object after some inserts and copies it to a new space in memory. It does not care about deletions. So when this happens, the loop notices it and breaking with an exception.
Check out this link if you want to read more about this, and many other interesting python internals here.
https://github.com/satwikkansal/wtfpython#-modifying-a-dictionary-while-iterating-over-it
I just tested your code in python2 and python3
python3 output
0,1,2,3,4
python2
0,1,2,3,4,5,6,7
One thing comes to mind that could be going on. Either there is only a certain amount of memory being allocated in your dictionary when you create the first key value and when you delete the key value we do not allocate any memory or deallocate the memory you are just removing the value. Once all the allocated memory is used it exits. Because if you run without that del you will get this error
RuntimeError: dictionary changed size during iteration
So python creates enough memory for that key value and a few more and once it is used up theres no more memory allocated for your dictionary.
As many pointed out, modifying a datastructure during iteration with a for loop is not a good idea. The while loop though does allow that as it re-evaluates its loop condition at each iteration (I'm impressed nobody suggested that as alternative yet). One just has to find the right loop condition. Your script would have to become:
x = {0: None}
while x:
i, _ = x.popitem()
print(i)
# to avoid infinite loop while testing
# if i == 10:
# break
x[i+1] = None
In Python, a dictionary is falsy when it is empty (see docs), so the loop will only stop if at the beginning of an iteration x is empty.
Since the dictionary only has one key-value pair, popitem() should be enough to get that pair and remove it from the dictionary. As the next integer is added right after the dictionary is emptied, the loop condition will never be false when evaluated thereby resulting in an infinite loop.
I have a while loop below the commented out portions are from a previous test.
My hope was that the while loop would execute the methods from top to bottom and as the methods finish the methods below would start.
My hope felt valid as when the code was not in a while loop that was what was happening. Or maybe it just seemed that way?
My point is the code is executing in such a way that my assumption above seems wrong.
can any one please explain this to me?
counter = (len(cities)-1)
count = 0
while count != counter:
setCity(cities[count])
getApiData()
#populateVars()
#storeInDatabase()
#goToNextPage()
count +=1
storeData.createCSV(OTS.CSVname)
storeData.purgeDatabase()
Just iterate over the array without an index:
for city in cities:
setCity(city)
getApiData()
It seems that the code is indeed being run sequentially, unless there's some concurrency behind the scenes that you don't know about or aren't mentioning.
Regarding your code as it is, I think you're mistakenly subtracting 1 from len(cities); and anyhow, you should just iterate directly over the cities using a for loop.
for city in cities:
setCity(city)
getApiData()
# populateVars()
# storeInDatabase()
# goToNextPage()
storeData.createCSV(OTS.CSVname)
storeData.purgeDatabase()
I will update this answer if there are any changes/clarifications.
I have a kinda weird problem, here is my attempt at an explanation:
I'm currently making a program which opens a txt file and then reads a line for that file, using the following command linecache.getline(path,number), after the function is done I then use commmand linecache.clearcache.
If I then change something in the text file it keeps returning the pre-changed line.
Following is the code I'm using (I know it aint really pretty)
def SR(Path,LineNumber):
returns = lc.getline(Path,LineNumber)
x = np.array([])
y = np.array([])
words = returns.split()
for word in words:
x = np.append([x],[word])
for i in range(len(x)):
t = float(x[i])
y = np.append([y],[t])
return y
del x
del y
del t
del words
lc.clearcache()
Nothing after the return statement will ever be executed. If you want to call clearcache, you need to call it before the return statement.
Also, as a side note, your del statements aren't really going to do anything either, even if they were placed before the return. del effectively just decrements the reference counter in the gc, which will happen when the interpreter exits the function scope anyway.
I have post the similar question before,but this time the problem is different,I got stuck with the following code..can anyone help with it?thanks in advance
I have fixed mu code as suggested,thanks
from numpy import *
#vs,fs,rs are all m*n matrixs,got initial values in,i.e vs[0],fs[0],rs[0] are known
#want use this foor loop to update them
vs=zeros((10,3))
vs[0]=([1,2,3])
fs=zeros((10,3))
fs[0]=([2,3,4])
vs=zeros((10,3))
vs[0]=([3,4,5])
for i in range(5):
#start looping..
vs[i+1]=vs[i]+fs[i]
fs[i+1]=(rs[i]-re[i])
rs[i+1]=rs[i]+vs[i]
print vs,fs,rs
then this code gives vs,fs,rs in different i,but not update each rows of rs,fs,vs and return me a single array of rs,fs,vs (fully updated). whats the problem here?..what should I add?thanks
Put your inizialization outside the loop! Right now, you're resetting the arrays to all zeros each time through the loop, over and over, which is absurd. You also appear to have a typo -- you set vs twice and rs never -- so I've tried to guess what you meant.
from numpy import *
#vs,fs,rs are all m*n matrixs,got initial values in,i.e vs[0],fs[0],rs[0] are known
#want use this foor loop to update them
vs=zeros((10,3))
vs[0]=([1,2,3])
fs=zeros((10,3))
fs[0]=([2,3,4])
rs=zeros((10,3))
rs[0]=([3,4,5])
for i in range(5):
#start looping..
vs[i+1]=vs[i]+fs[i]
fs[i+1]=rs[i]-re[i]
rs[i+1]=rs[i]+vs[i]
print vs,fs,rs
You do not start looping where the comment indicates it, but at the for i in range(5): line. Everything in the indented block (the "body of the for-loop") is done repeatedly for each i. So setting vs and fs to zero is done repeatedly, each time deleting what was calculated before. These initializations should be done before the for.
Also vs is initialized twice while rs isn't initialized at all, probably that's a typo and it should look like this:
vs=zeros((10,3))
vs[0]=([1,2,3])
fs=zeros((10,3))
fs[0]=([2,3,4])
rs=zeros((10,3))
rs[0]=([3,4,5])
for i in range(5):
#start looping..
...
I don't know exactly what you want to print. If you want to print every matrix every time it is updated, then you're fine. But if you want to print the matrices after all the updates have been completed, then you should bring that print statement out of the for loop.
This and what Alex and sth have said should fix your code fully