0

I'm new to Python and start to learn using a book. I've run into this issue that the for loop is not running through all the items in the list regardless of how many items in the list.The debugging does not give much insight to it. Can someone please explain me what's happening? Thanks in advance.

sandwich_orders = ['italian','beef','chicken','tuna','cheese','pork','salami']

finished_sand = []


for sands in sandwich_orders:
    temp_sand = sandwich_orders.pop()
    finished_sand.append(temp_sand)

for items in finished_sand:
    print(f"\nI've finished the {items} sandwich order")


print(finished_sand)

output-

I've finished the salami sandwich order

I've finished the pork sandwich order

I've finished the cheese sandwich order

I've finished the tuna sandwich order
['salami', 'pork', 'cheese', 'tuna']
Sahan Dissanayaka
  • 591
  • 2
  • 8
  • 26

5 Answers5

1

What's happening in your code is when you do:

for sands in sandwich_orders:
    temp_sand = sandwich_orders.pop()
    finished_sand.append(temp_sand)

you're poping an element from sandwich_orders in each iteration. The list contains 7 elements at the start, but after 4 iterations, you have already popped the last 4 elements from sandwich_orders, and there is nothing left to iterate through. That's why you're only seeing 4 outputs.

Try this:

for sands in range(len(sandwich_orders)):
    temp_sand = sandwich_orders.pop()
    finished_sand.append(temp_sand)

for items in finished_sand:
    print(f"\nI've finished the {items} sandwich order")
Chen Ni
  • 979
  • 1
  • 12
  • 24
0

There is no need to pop elements, you can directly append and print them.

sandwich_orders = ['italian','beef','chicken','tuna','cheese','pork','salami']
finished_sand = []
for sands in sandwich_orders:
   finished_sand.append(sands)
for items in finished_sand:
    print(f"\nI've finished the {items} sandwich order")
user1465978
  • 61
  • 2
  • 10
  • Yes there is no need to pop() but that's the requirement of the exercise I'm working on. At the end of the program the sandwich_order list should be empty, hence I used the pop() method. Thank you. – Malith Perera Jun 25 '20 at 03:01
0

The main issue here is you are using the .pop() method on the list. This removes the last item and returns it. See here: https://docs.python.org/2/tutorial/datastructures.html

Your for loop is first popping and then moving on to the next sandwich, which is why you only ended up with 4 elements. This is also not a recommended way to operate on lists as the pop method removes data. You should only use this if your application absolutely must have this feature, which is usually very unlikely.

The correct python way would be to simply iterate over the list and append to a target list.

It is not recommended to create an empty list simply for the purpose of iteration but if you must then this is how you would do it with your temporary list:

sandwich_orders = ['italian','beef','chicken','tuna','cheese','pork','salami']

finished_sand = []
for sands in sandwich_orders: 
    finished_sand.append(sands) # notice you can directly append to finished_sands on each iteration
    sandwich_orders.pop() # if pop is a requirement then pop *after* you append 

for items in finished_sand: 
    print(f"\nI've finished the {items} sandwich order")

print(finished_sand)
 

# Recommended Python version
sandwich_orders = ['italian', 'beef', 'chicken', 'tuna', 'cheese', 'pork', 'salami']
for sandwich in sandwich_orders:
    print(f"\nI've finished the {sandwich} sandwich order")

The recommended version is much simpler and is easier to read while removing the need to duplicate lists. For learning it is okay but in practice you should rethink your program logic to follow Python best practices.

Also please indent your code as per PEP8

for x in y: print(x) # syntactically valid but not PEP8 

# structure code with indents , more readable and adheres to standards
for x in y:
    print(x)


0

When you call .pop(), you are modifying a list while iterating over it.
As a general rule, you never want to do that, as unexpected results will happens.

A clear explanation of what happens is described in this SO post:
strange result when removing item from a list

Yusef Maali
  • 2,201
  • 2
  • 23
  • 29
0

In the first for loop which you have written, like so,

for sands in sandwich_orders:
    temp_sand = sandwich_orders.pop()
    finished_sand.append(temp_sand)

the sands variable is moving from the left to right in every loop iteration, while the pop() operation is removing elements from right to left direction. To visualize, take a look at the following,

    *sands*                                           *pop*
['italian','beef','chicken','tuna','cheese','pork','salami'] #iteration1

            *sands*                         *pop*       
['italian','beef','chicken','tuna','cheese','pork'] #iteration2

                    *sands*          *pop*            
['italian','beef','chicken','tuna','cheese'] #iteration3

                             *pop*
                             *sands*            
['italian','beef','chicken','tuna'] #iteration4

after iteration 4, now sands variable doesn't have anymore elements to iterate. Meanwhile, you have added 'tuna','cheese','pork','salami' to the new list finished_sand

mettleap
  • 1,390
  • 8
  • 17
  • Thank you sir for the explanation! I've changed the code to below and it worked. Thank you everyone! while sandwich_orders: for sands in sandwich_orders: temp_sand = sands finished_sand.append(temp_sand) sandwich_orders.remove(sands) – Malith Perera Jun 25 '20 at 03:19
  • @MalithPerera, would appreciate it if you upvote/accept this answer if you find it useful. :) you're welcome! – mettleap Jun 25 '20 at 03:21
  • I did vote but it's saying that it's recorded. Thank you. – Malith Perera Jun 25 '20 at 03:35
  • This illustration is really clear :) – Chen Ni Jun 25 '20 at 08:12