REALLY need help with iterating a list.

R

Radamand

This has been driving me buggy for 2 days, i need to be able to
iterate a list of items until none are left, without regard to which
items are removed. I'll put the relevant portions of code below,
please forgive my attrocious naming conventions.
Basically i'm trying to spin up some subprocesses that will ping a
group of servers and then wait until all of them have completed (good
or bad), store the ping result and the return code, and move on.
The problem comes in the second block, when i try to iterate the
list of servers and remove the ones that are finished, for some reason
Python appears to re-index the list when I remove an item and the next
step through the loop it cant find the item its expecting because the
indexes have changed.
Any assistance would be appreciated...

=============================================================================
for server in serverlist:
ping[server] = subprocess.Popen("ping -c 1 " + str(server) + " 5",
shell=True, stdout=subprocess.PIPE)

while len(serverlist) > 0:
for server in serverlist:
if ping[server].returncode==None:
ping[server].poll()
else:
pingresult[server] = ping[server].stdout.read()
pingreturncode[server] = ping[server].returncode
serverlist.remove(server)
 
A

alg

Reverse iteration should do the trick, if I understand your problem:

for server in reversed(serverlist):
...
else:
serverlist.remove(server)
 
I

infidel

This has been driving me buggy for 2 days, i need to be able to
iterate a list of items until none are left, without regard to which
items are removed. I'll put the relevant portions of code below,
please forgive my attrocious naming conventions.
Basically i'm trying to spin up some subprocesses that will ping a
group of servers and then wait until all of them have completed (good
or bad), store the ping result and the return code, and move on.
The problem comes in the second block, when i try to iterate the
list of servers and remove the ones that are finished, for some reason
Python appears to re-index the list when I remove an item and the next
step through the loop it cant find the item its expecting because the
indexes have changed.
Any assistance would be appreciated...

=============================================================================
for server in serverlist:
ping[server] = subprocess.Popen("ping -c 1 " + str(server) + " 5",
shell=True, stdout=subprocess.PIPE)

while len(serverlist) > 0:
for server in serverlist:
if ping[server].returncode==None:
ping[server].poll()
else:
pingresult[server] = ping[server].stdout.read()
pingreturncode[server] = ping[server].returncode
serverlist.remove(server)

How about something like this?

while serverlist:
server = serverlist.pop(0)
pinger = ping[server]
if pinger.returncode==None:
pinger.poll()
serverlist.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode

Basic idea: as long as there are servers in the list, pop the first
one out of the list, see if it's done, and if it isn't, put it back on
the end of the list.
 
F

Fredrik Lundh

infidel said:
How about something like this?

while serverlist:
server = serverlist.pop(0)
pinger = ping[server]
if pinger.returncode==None:
pinger.poll()
serverlist.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode

Basic idea: as long as there are servers in the list, pop the first
one out of the list, see if it's done, and if it isn't, put it back on
the end of the list.

here's a simple variation of that, which is a bit more efficient, and
perhaps also a bit easier to use in the general case:

while serverlist:
still_active = []
for server in serverlist:
pinger = ping[server]
if pinger.returncode is None:
pinger.poll()
still_active.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode
serverlist = still_active

</F>
 
R

Radamand

infidel said:
How about something like this?
while serverlist:
server = serverlist.pop(0)
pinger = ping[server]
if pinger.returncode==None:
pinger.poll()
serverlist.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode
Basic idea: as long as there are servers in the list, pop the first
one out of the list, see if it's done, and if it isn't, put it back on
the end of the list.

here's a simple variation of that, which is a bit more efficient, and
perhaps also a bit easier to use in the general case:

while serverlist:
still_active = []
for server in serverlist:
pinger = ping[server]
if pinger.returncode is None:
pinger.poll()
still_active.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode
serverlist = still_active

</F>

Thats an interesting approach but, if the returncode for a given
server is None say, 20 times in a row you will have append'ed that
server to the list 20 times, i suppose you could check the list to see
if its already there but thats a bit kludgey...

also, the line "pinger = ping[server]" would have to be extracted from
this loop otherwise your going to ping the same server repeatedly
until it answers...
 
R

Radamand

This has been driving me buggy for 2 days, i need to be able to
iterate a list of items until none are left, without regard to which
items are removed. I'll put the relevant portions of code below,
please forgive my attrocious naming conventions.
Basically i'm trying to spin up some subprocesses that will ping a
group of servers and then wait until all of them have completed (good
or bad), store the ping result and the return code, and move on.
The problem comes in the second block, when i try to iterate the
list of servers and remove the ones that are finished, for some reason
Python appears to re-index the list when I remove an item and the next
step through the loop it cant find the item its expecting because the
indexes have changed.
Any assistance would be appreciated...
=============================================================================
for server in serverlist:
ping[server] = subprocess.Popen("ping -c 1 " + str(server) + " 5",
shell=True, stdout=subprocess.PIPE)
while len(serverlist) > 0:
for server in serverlist:
if ping[server].returncode==None:
ping[server].poll()
else:
pingresult[server] = ping[server].stdout.read()
pingreturncode[server] = ping[server].returncode
serverlist.remove(server)

How about something like this?

while serverlist:
server = serverlist.pop(0)
pinger = ping[server]
if pinger.returncode==None:
pinger.poll()
serverlist.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode

Basic idea: as long as there are servers in the list, pop the first
one out of the list, see if it's done, and if it isn't, put it back on
the end of the list.

I like this idea, ill try it out asap.

ok, tried it, works perfectly!! It never occurred to me to use pop to
pull one off and put it back on if it wasnt done, very nice! Thank
You!!
 
G

Gabriel Genellina

here's a simple variation of that, which is a bit more efficient, and
perhaps also a bit easier to use in the general case:

while serverlist:
still_active = []
for server in serverlist:
pinger = ping[server]
if pinger.returncode is None:
pinger.poll()
still_active.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode
serverlist = still_active

</F>

Thats an interesting approach but, if the returncode for a given
server is None say, 20 times in a row you will have append'ed that
server to the list 20 times, i suppose you could check the list to see
if its already there but thats a bit kludgey...

Read the code again and notice that there are TWO lists involved. There is
at most one append per server - unless there are duplicates in the
original list, the new list won't have any.
also, the line "pinger = ping[server]" would have to be extracted from
this loop otherwise your going to ping the same server repeatedly
until it answers...

Uh...?
 
F

Fredrik Lundh

Radamand said:
while serverlist:
still_active = []
for server in serverlist:
pinger = ping[server]
if pinger.returncode is None:
pinger.poll()
still_active.append(server)
else:
pingresult[server] = pinger.stdout.read()
pingreturncode[server] = pinger.returncode
serverlist = still_active

</F>

Thats an interesting approach but, if the returncode for a given
server is None say, 20 times in a row you will have append'ed that
server to the list 20 times
>
also, the line "pinger = ping[server]" would have to be extracted from
this loop otherwise your going to ping the same server repeatedly
until it answers...

did you miss that there are two loops here? the inner loop loops over
the available servers, and add servers that needs to be checked again to
a *new* list. that list is then assigned to the original serverlist
variable.

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top