Python Forum
How to remove some elements from an array in python?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to remove some elements from an array in python?
#1
I have a sorted list of integers that has about 4000 elements. I'm trying to remove every element that is above 550. I used remove() function for the task but it doesn't seem to work. I also looked into pop, tried it and it doesn't seem to work to because pop I think is for storing single data while also removing it from the original list. I also tried del() function. Since my list is sorted, I could use the del to remove the numbers above 550 just by figuring out from what index the element starts.

Here is my current code using the remove() function:
sorted_MD_list = sorted(MD_list)

for i in sorted_MD_list:
    if i > 550:
        sorted_MD_list.remove(i)

print(sorted_MD_list)
The result when i print the sorted list is the same list including the values that are above 550.
buran write Nov-28-2023, 08:18 AM:
Please, use proper tags when post code, traceback, output, etc. This time I have added tags for you.
See BBcode help for more info.
Reply
#2
Please use bbtags when posting code.

Here is one way

# Create a list
alist = [i for i in range(50)]
sorted(alist)

print(alist)
print()
# Create a copy of the list.
# Should not try to edit a list that you are iterating over
alist_copy = alist.copy()

# Iterate over the copy and remove anything above chosen number
# from original list
for index, number in enumerate(alist_copy):
    if number > 20:
        alist.remove(number)

print(alist)
Output
Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
gohanhango likes this post
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#3
This is because you're altering the list object as you iterate over it. The way that I would do this is to have your .remove() loop compile a list of values that need to be removed, than use that list to find and remove the values from the sorted_MD_list.
gohanhango likes this post
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply
#4
(Nov-28-2023, 12:17 AM)menator01 Wrote: Please use bbtags when posting code.

Here is one way

# Create a list
alist = [i for i in range(50)]
sorted(alist)

print(alist)
print()
# Create a copy of the list.
# Should not try to edit a list that you are iterating over
alist_copy = alist.copy()

# Iterate over the copy and remove anything above chosen number
# from original list
for index, number in enumerate(alist_copy):
    if number > 20:
        alist.remove(number)

print(alist)
Output
Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

Hello, sorry but I don't know how to do the bbtags. As for the code. Wow! It works. Why is that? Why can't I iterate over the original list?
Reply
#5
(Nov-28-2023, 01:54 AM)gohanhango Wrote: Why can't I iterate over the original list?

If you think about it, if you have a list of 1,2,3,4,5 and you iterate over that with a for n in lst: loop, n will return each element in turn, but if you remove one of the elements mid loop (say when n == 3) the next element becomes 5, not 4, because each element is shifted one index to the left to fill the now vacated index position: the 4 to where the 3 was and the 5 to where the 4 was.
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply
#6
(Nov-28-2023, 12:18 AM)rob101 Wrote: This is because you're altering the list object as you iterate over it. The way that I would do this is to have your .remove() loop compile a list of values that need to be removed, than use that list to find and remove the values from the sorted_MD_list.

Thank you.
rob101 likes this post
Reply
#7
I would delete a slice.
values = list(range(1, 4001))
for index, value in enumerate(values):
    if value >= 550:
        del values[index:]
        break
print(len(values))
Output:
549
If it is ok to reassign the list, I would make a slice.
values = list(range(1, 4001))
for index, value in enumerate(values):
    if value >= 550:
        values = values[:index]
        break
print(len(values))
For a tiny list like 4000 values the difference between deleting a slice and using remove is zero time to maybe 1/10th of a second. For a list with hundreds of millions of values the difference becomes significant.
Reply
#8
I would have used numpy and np.where + np.delete (it has been fully detailled here after to see how it works); actually only lines 9-11-12-(22) are necessary.

import numpy as np

# a list is created first using numpy
N = 5_000
M = np.random.randint(-2, 10_000, size=(N)).tolist()

# it starts here
MaxNumber = 4_000
Mat = np.asarray(M)

Ind = np.where(Mat >= MaxNumber)
n = np.shape(Ind)[1]
print(f"There's {n} elements to remove")

Mat = np.delete(Mat, np.s_[Ind])

# you can of course sort the array if it's needed
Indexes = Mat.argsort()
MatSorted = Mat[Indexes]

# now you can go back to a list
M_new = MatSorted.tolist()
Reply
#9
Others have already explained why you should not remove elements from a list while iterating over it.
Given that you have sorted list, this is very nice use case for bisect module from Standard Library

import random
import bisect

# create sorted list of 10 elements
spam = sorted([random.randint(1, 100) for _ in range(10)])
print(spam)

# remove all elements equal or greater than 42
cutoff = bisect.bisect_left(spam, 42)
eggs = spam[:cutoff]
print(eggs)
Output:
[19, 31, 32, 32, 44, 47, 61, 68, 70, 85] [19, 31, 32, 32]
You can explore also other module level functions
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#10
If the list is sorted, you can simply use bisect which performs a logarithmic search
import random
import bisect

# create sorted list of numbers
alist = sorted(random.choices(range(10000), k=4000))

# find insertion point to the right of a given value
index = bisect.bisect_right(alist, 550)
# keep only elements lower or equal to the given value
alist[:] = alist[:index]

print(alist)
« We can solve any problem by introducing an extra level of indirection »
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  unable to remove all elements from list based on a condition sg_python 3 458 Jan-27-2024, 04:03 PM
Last Post: deanhystad
  ValueError: Length mismatch: Expected axis has 8 elements, new values have 1 elements ilknurg 1 5,168 May-17-2022, 11:38 AM
Last Post: Larz60+
  Replace elements of array with elements from another array based on a third array Cola_Reb 6 1,883 May-13-2022, 06:06 PM
Last Post: deanhystad
Question Change elements of array based on position of input data Cola_Reb 6 2,143 May-13-2022, 12:57 PM
Last Post: Cola_Reb
  Indexing [::-1] to Reverse ALL 2D Array Rows, ALL 3D, 4D Array Columns & Rows Python Jeremy7 8 7,155 Mar-02-2021, 01:54 AM
Last Post: Jeremy7
  Sorting Elements via parameters pointing to those elements. rpalmer 3 2,614 Feb-10-2021, 04:53 PM
Last Post: rpalmer
  4D array with only elements on one side of the diagonal schniefen 0 1,696 Dec-24-2020, 11:32 AM
Last Post: schniefen
  Removing some elements from array based on a condition claw91 0 1,523 Oct-27-2020, 03:42 PM
Last Post: claw91
  Remove specific elements from list with a pattern Xalagy 3 2,727 Oct-11-2020, 07:18 AM
Last Post: Xalagy
  remove elements method not working spalisetty06 4 2,488 Aug-13-2020, 01:17 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020