Python Forum
output list reducing each time through loop - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: output list reducing each time through loop (/thread-16418.html)



output list reducing each time through loop - 3Pinter - Feb-27-2019

In getting empty lists as output, and that is something I don't get.

Expected:
[1,2,3,4,5]
[2,3,4,5]
[3,4,5]
[4,5]
[5]

a = [1,2,3,4,5]
output = []

while a:
  output.append(a)
  a.pop(0)

print(output)
I want a seperate 'output'container so I can use that afterwards.


RE: output list reducing each time through loop - buran - Feb-27-2019

You are getting list of empty lists, not empty list
Output:
[[], [], [], [], []] >>>
Check this link https://nedbatchelder.com/text/names.html
lists are mutable. when you append a to output on line 5, every list you append refers to same elements. when you pop element on line 6 you pop it out from all the lists. To fix this, you need to append copy of a to output
a = [1,2,3,4,5]
output = []
 
while a:
  output.append(a[:])
  a.pop(0)
 
print(output)
Output:
[[1, 2, 3, 4, 5], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5]] >>>



RE: output list reducing each time through loop - 3Pinter - Feb-28-2019

Thanks Buran,

I think it makes sense to me, but I'll read the link you posted so I can fully understand it! Food for thought!

3Pinter


RE: output list reducing each time through loop - 3Pinter - Mar-19-2019

Hey Buran,

Super interesting article and it explained a lot to me. However I don't get a tiny thing: lists are mutable, okay. And therefor doing this:

start = [1,2,3,4,5]
new = []
t = True
for s in start:
    new.append(start)
    if t:
    	start.pop(0)
        t = False
print(new)
"new" will output [2,3,4,5] a few times. As expected.

But since lists are mutable I would expect that changing "start" to a new definition would alter the "new" list as well.

start = [1,2,3,4,5]
new = []
t = True
for s in start:
    new.append(start)
    if t:
    	start.pop(0)
        t = False
start = ["test"]
print(new)
But python will still output [2,3,4,5] a few times.

Why doesn't it output "test" a few times?


RE: output list reducing each time through loop - buran - Mar-19-2019

on line 9 you don't mutate start, you create new list, i.e. start now points to different list:

start = [1,2,3,4,5]
print(f'id of start: {id(start)}')
new = []
print(f'id of new: {id(new)}')
t = True
for s in start:
    new.append(start)
    if t:
        start.pop(0)
        t = False
start = ['test']
print(f'id of start: {id(start)}')
print(new)
print(f'id of new: {id(new)}')
Output:
id of start: 4088456 id of new: 32132424 id of start: 32124040 [[2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5]] id of new: 32132424 >>>
as you can see the id of start changes, while the id of new is the same


Now, here is what you were looking/expecting:

start = [1,2,3,4,5]
print(f'id of start: {id(start)}')
new = []
print(f'id of new: {id(new)}')
t = True
for s in start:
    new.append(start)
    if t:
        start.pop(0)
        t = False
print(new)
start[0] = 'test'
print(f'id of start: {id(start)}')
print(new)
print(f'id of new: {id(new)}')
Output:
id of start: 4153992 id of new: 31997384 [[2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3, 4, 5]] id of start: 4153992 [['test', 3, 4, 5], ['test', 3, 4, 5], ['test', 3, 4, 5], ['test', 3, 4, 5]] id of new: 31997384 >>>
here you mutate the original start (id is not changed) and you can see that change is also reflected in new


RE: output list reducing each time through loop - 3Pinter - Mar-19-2019

ah, python too has id's. that explains it all.

Thanks again Buran for your explanation!


RE: output list reducing each time through loop - perfringo - Mar-19-2019

Additional tidbit: if you really after "output 'test' few times" then it can be done this way:

start[:] = ['test']