Efficient way to remove objects from a list

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?GB2312?B?0rvK18qr?=

    Efficient way to remove objects from a list

    Hi all,

    Today I wrote some code like this:

    for m in self.messages:
    if not m.finished:
    continue

    #process the message

    fini = [m for m in self.messages if m.finished]
    for m in fini:
    self.messages.r emove(m)

    As you can, I want to find these finished messages in
    "self.messages" ,
    process them, and then remove them from the list.

    Because a list can not be modified while iterating it, I have to use
    a list "fini" to accomplish the target.

    I found a smell of bad performance here.
    Is there any faster ways?
  • Peter Otten

    #2
    Re: Efficient way to remove objects from a list

    Chris Rebert wrote:
    On Mon, Nov 3, 2008 at 1:40 AM, 一首诗 <newptcai@gmail .comwrote:
    >Hi all,
    >>
    >Today I wrote some code like this:
    >>
    >
    Build a new list as you go, then overwrite the old list with it.
    >
    unfinished = []
    >
    > for m in self.messages:
    > if not m.finished:
    unfinished.appe nd(m)
    > continue
    >>
    > #process the message
    >>
    >
    Remove the following code
    >
    > fini = [m for m in self.messages if m.finished]
    > for m in fini:
    > self.messages.r emove(m)
    >
    self.messages[:] = unfinished
    Just

    self.messages = unfinished

    if also OK unless you have multiple references to the self.messages list.
    This way you aren't calling .remove() multiple times and only iterate
    through the list once.

    Comment

    • =?GB2312?B?0rvK18qr?=

      #3
      Re: Efficient way to remove objects from a list

      Thanks! That's a more clear way!

      On Nov 3, 9:38 pm, Peter Otten <__pete...@web. dewrote:
      Chris Rebert wrote:
      On Mon, Nov 3, 2008 at 1:40 AM, Ò»Ê×Ê« <newpt...@gmail .com>wrote:
      Hi all,
      >
      Today I wrote some code like this:
      >
      Build a new list as you go, then overwrite the old list with it.
      >
      unfinished = []
      >
      for m in self.messages:
      if not m.finished:
      unfinished.appe nd(m)
      continue
      >
      #process the message
      >
      Remove the following code
      >
      fini = [m for m in self.messages if m.finished]
      for m in fini:
      self.messages.r emove(m)
      >
      self.messages[:] = unfinished
      >
      Just
      >
      self.messages = unfinished
      >
      if also OK unless you have multiple references to the self.messages list.
      >
      This way you aren't calling .remove() multiple times and only iterate
      through the list once.
      >
      >

      Comment

      Working...