0

I am trying to modify a list while in a loop.

Lets assume that we have a class called Node with 3 properties (Node.x, Node.y, Node.z). There are two lists filled with N and M occasions of the object Node.

I am trying to have bilateral matches/connections between two lists so after each pairing the initial objects has to be modified in order to continue with comparing the other pairs.

This is a sample code described above.

offer =  [ Node_o1, Node_o2, ...., Node_oN ] 
demand = [ Node_d1, Node_d2,...., Node_dM  ]
connections = []
disThresh = 100

for i in offer:
    for j in demand:
        dist = Distance(i,j)
        if dist < disThresh and min(i.z, j.z) > 0: #if there is z available to send
            print 'Connected offer %r with demand %r. Dist: %r' % (i , j, dist)
            link = min(i.z, j.z)
            i.z = i.z - link
            j.z = j.z - link
            connections.append([i,j])

After the half of the iterations the program behaves very strangely, because apparently it uses the initial data from the iterator and not the modified. I have tried to iterate on a copy of the list (offer[:]) but still it does not work. While loops or enumerators (for i,v in enumerate(offer):) do not work either.

Could you propose an elegant working approach to this problem? Thank you in advance.

kots
  • 19
  • 7
  • 2
    Put some test cases up that don't work as expected. – user3556757 Oct 21 '14 at 13:04
  • You are right. I corrected the code to reflect your comment. The same question still applies. The logic is that a specific amount of z is now reserved for the link so potential new links will examine only the what is left – kots Oct 21 '14 at 13:05

1 Answers1

0

You should change the for loop. Instead of using an iterator use indexes in the offer and demand arrays:

for i in xrange(len(offer)):
    for j in xrange(len(demand)):
        #code here

If you iterate on a copy of the list you won't see the modifications. Similarly if you use an iterator it won't work: Modifying list while iterating

I modified your code in the following way, logic won't be exactly the same since I don't know what's inside your objects but you can see lists are modified in place and modifications are visible while iterating.:

offer =  [ 1, 8, 3 ]
demand = [ 1, 10, 11, 7 ]
connections = []
disThresh = 100

for i in xrange(len(offer)):
    for j in xrange(len(demand)):
        dist = offer[i] - demand[j]
        if dist < disThresh and min(offer[i], demand[j]) > 0: #if there is z available to send                                                                                                                                                                                
            link = min(offer[i], demand[j])
            offer[i] = offer[i] - link
            demand[j] = demand[j] - link
            connections.append([i,j])
            print "Connected ",i,"and",j,"offer",offer,"demand",demand

print connections
Community
  • 1
  • 1
igon
  • 3,016
  • 1
  • 22
  • 37
  • Thanks! It worked with a similar approach. The code is less elegant but i guess i cant have it all. – kots Oct 21 '14 at 13:41