Posts: 17 Threads: 11 Joined: Dec 2020 Hi there! I'm trying to leave out a specific integer in a list and remove every other number nr = 9 my_list = [0,5,6,7,6,9,9,1,9] for i in my_list: if i is not nr: my_list.remove(i) print(my_list) However I get [5, 7, 9, 9, 9] instead of [9,9,9] What am I doing wrong? Posts: 1,589 Threads: 3 Joined: Mar 2020 If you modify an object while iterating over it, it can cause problems. Either iterate over a copy of it, or copy the data you do need and don't copy the rest. Examples: Iterate over a copy: nr = 9 my_list = [0,5,6,7,6,9,9,1,9] for i in my_list[:]: if i is not nr: my_list.remove(i) print(my_list) Pull out the data you want, and overwrite the old reference nr = 9 my_list = [0,5,6,7,6,9,9,1,9] my_list = [x for x in my_list if x == nr] print(my_list) Posts: 17 Threads: 11 Joined: Dec 2020 Dec-18-2020, 09:30 PM (This post was last modified: Dec-18-2020, 09:31 PM by GJG.) Posts: 6,920 Threads: 22 Joined: Feb 2020 As bowlofred mentions, the two examples not only solve the problem in different ways, but produce different results. The difference may be an unimportant side-effect, or it might break your code. nr = 9 numbers = [0,5,6,7,6,9,9,1,9] # This createa a new list nines = [x for x in numbers if x == nr] print('New List', nines, numbers) # This code modifies the list nines = numbers for x in nines[:]: if x != nr: nines.remove(x) print('Modifies', nines, numbers)Output: New List [9, 9, 9] [0, 5, 6, 7, 6, 9, 9, 1, 9] Modifies [9, 9, 9] [9, 9, 9]
Notice that the list comprehension does not change the original list. The remove.() for loop looks clunky, but it does modify the original list. All references to the list will see the changes. Posts: 17 Threads: 11 Joined: Dec 2020 Thanks deanhystad! By the way, in the block that modifies a list, you added: nines = numbers for x in nines[:]: rather than going straight to for x in numbers[:] Is there any particular reason for it? Sorry for all the noobish questions :) Posts: 8,198 Threads: 162 Joined: Sep 2016 Dec-19-2020, 09:37 AM (This post was last modified: Dec-19-2020, 09:38 AM by buran.) (Dec-19-2020, 08:31 AM)GJG Wrote: Is there any particular reason for it? I guess he did it in order to preserve the original list and be able to show the original unmodified list to you afterwards. Ops, that was stupid comment on my side. It shows that nines and numbers are actually the same [mutable] object and when modify mutable objects you need to be careful. nines = numbers does not creaty a copy of numbers, it just binds name nines to same object as numbers Posts: 17 Threads: 11 Joined: Dec 2020 So basically there's no point for it..? Posts: 8,198 Threads: 162 Joined: Sep 2016 Dec-19-2020, 05:18 PM (This post was last modified: Dec-19-2020, 05:18 PM by buran.) (Dec-19-2020, 04:55 PM)GJG Wrote: So basically there's no point for it..? yes nr = 9 numbers = [0,5,6,7,6,9,9,1,9] for x in numbers[:]: if x != nr: numbers.remove(x) print(numbers) Output: [9, 9, 9]
by the way - you can try it yourself. don't hesitate to experiment and play with the code. |