0

I have a for loop as below in python 3.4

def checkCustometers(self):
    for customer in self.customers_waiting:
        if customer.Source == self.location: #if the customer wants to get on at this floor,
            self.customers_inside_elevators.append(customer) #place customer into elevator
            self.customers_waiting.remove(customer) #The customer isent waiting anymore

Lets say for example at

customer_waiting[4]
    if customer.Source == Self.location

Then the loops deletes

customer_waiting[4] and customer_waiting[5]

and goes to position 4. The loop then goes on and looks at customer_waiting[5] but its is actually looking at customer_waiting[6] skipping customer_waiting[5]

How can i fix this?

jemminger
  • 5,133
  • 4
  • 26
  • 47
bpb101
  • 971
  • 1
  • 9
  • 18
  • The duplicate is also a duplicate: http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python – Selcuk Mar 15 '15 at 20:32

2 Answers2

1

You need to make a copy or use reversed:

def checkCustometers(self):
    for customer in self.customers_waiting[:]:
        if customer.Source == self.location: #if the customer wants to get on at this floor,
            self.customers_inside_elevators.append(customer) #place customer into elevator
            self.customers_waiting.remove(customer)

Using reversed:

def checkCustometers(self):
    for customer in reversed(self.customers_waiting):
        if customer.Source == self.location: #if the customer wants to get on at this floor,
            self.customers_inside_elevators.append(customer) #place customer into elevator
            self.customers_waiting.remove(customer)

Never mutate a list you are iterating over without copying or using reversed or you will end up skipping elements as you have already seen, if you remove an element you change which element python was pointing to a a certain position when you started the iteration .

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
0

If you try to mutate the list while iterating over it, expect to see such results.

How about a clean way instead:

def checkCustometers(self):
    self.customers_inside_elevators += [c for c in self.customers_waiting if c.Source == self.location]
    self.customers_waiting = [c for c in self.customers_waiting if c.Source != self.location]
UltraInstinct
  • 43,308
  • 12
  • 81
  • 104