list partition

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Moosebumps

    list partition

    Is there a function that takes a list and predicate, and returns two
    lists -- one for which the predicate is true and one for which it is false?

    I know I can call filter(p, list) and filter( not p, list) or something like
    that, but I assume it would be more efficient to do it in one pass.

    Actually I probably can't call "not p", I would have to wrap p in a function
    notP or something. Or is there a shortcut for lambda(x) : not p(x)? I
    guess it isn't that long : )

    MB


  • Peter Otten

    #2
    Re: list partition

    Moosebumps wrote:
    [color=blue]
    > Is there a function that takes a list and predicate, and returns two
    > lists -- one for which the predicate is true and one for which it is
    > false?[/color]

    I take a slightly different approach, which is not limited to boolean
    predicates:
    [color=blue][color=green][color=darkred]
    >>> def predicate(v): return v & 1[/color][/color][/color]
    ....[color=blue][color=green][color=darkred]
    >>> d = {}
    >>> for i in range(10):[/color][/color][/color]
    .... d.setdefault(pr edicate(i), []).append(i)
    ....[color=blue][color=green][color=darkred]
    >>> d[True][/color][/color][/color]
    [1, 3, 5, 7, 9][color=blue][color=green][color=darkred]
    >>> d[False][/color][/color][/color]
    [0, 2, 4, 6, 8][color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    Peter

    Comment

    • David M. Cooke

      #3
      Re: list partition

      At some point, "Moosebumps " <Moosebumps@Moo sebumps.Moosebu mps> wrote:
      [color=blue]
      > Is there a function that takes a list and predicate, and returns two
      > lists -- one for which the predicate is true and one for which it is false?
      >
      > I know I can call filter(p, list) and filter( not p, list) or something like
      > that, but I assume it would be more efficient to do it in one pass.[/color]

      Not too hard to write your own:

      def filtersplit(p, iterable):
      ptrue = []
      pfalse = []
      for x in iterable:
      if p(x):
      ptrue.append(x)
      else:
      pfalse.append(x )
      return ptrue, pfalse
      [color=blue]
      > Actually I probably can't call "not p", I would have to wrap p in a function
      > notP or something. Or is there a shortcut for lambda(x) : not p(x)? I
      > guess it isn't that long : )[/color]

      itertools.ifilt erfalse negates the condition for you.

      --
      |>|\/|<
      /--------------------------------------------------------------------------\
      |David M. Cooke
      |cookedm(at)phy sics(dot)mcmast er(dot)ca

      Comment

      Working...