this is simple...

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

    this is simple...

    I am a newbie... and the first to admit it... but this has me stuffed:

    I have two lists A and B that are both defined as range(1,27) I want
    to find the entries that are valid for A = BxB

    so here is my code:

    A = range(1,27)
    B = range(1,27)

    for b in B:
    if b*b in A:
    print b
    else:
    B.remove(b)

    I get, as expected 1,4,9,16,25 printed out being the only members of B
    where the condition is true, but when I print B I get:

    [1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]

    1 to 5 is correct, but why doesn't the remove method remove 7 and
    above? What am I doing wrong here?
  • Mel

    #2
    Re: this is simple...

    ToshiBoy wrote:
    I have two lists A and B that are both defined as range(1,27) I want
    to find the entries that are valid for A = BxB
    [ ... ]
    I get, as expected 1,4,9,16,25 printed out being the only members of B
    where the condition is true, but when I print B I get:
    >
    [1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]
    >
    1 to 5 is correct, but why doesn't the remove method remove 7 and
    above? What am I doing wrong here?
    Try this:


    A = range(1,27)
    B = range(1,27)
    C = []

    for b in B:
    print "Trying", b
    if b*b in A:
    print b
    C.append (b)
    else:
    print "Removing", b
    B.remove(b)
    print 'B', B
    print 'C', C


    The essential problem is that your `B.remove`s are pulling the rug out from
    under your `for b in B:`. There are ways to mess with B while you iterate.
    Running though B backwards will do: `for b in B[::-1]:`, or iterating over
    a copy of B: `for b in B[:]:` or `for b in list(B):`. Leaving B alone and
    building up the desired items in C is probably simplest.

    Mel.

    Comment

    • Maric Michaud

      #3
      Re: this is simple...

      Le Saturday 28 June 2008 06:30:25 ToshiBoy, vous avez écrit :
      I am a newbie... and the first to admit it... but this has me stuffed:
      >
      I have two lists A and B that are both defined as range(1,27) I want
      to find the entries that are valid for A = BxB
      >
      so here is my code:
      >
      A = range(1,27)
      B = range(1,27)
      >
      for b in B:
      if b*b in A:
      print b
      else:
      B.remove(b)
      >
      I get, as expected 1,4,9,16,25 printed out being the only members of B
      where the condition is true, but when I print B I get:
      >
      [1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]
      >
      1 to 5 is correct, but why doesn't the remove method remove 7 and
      above? What am I doing wrong here?
      --
      http://mail.python.org/mailman/listinfo/python-list

      This is a frequent error from beginner, you're iterating over a list while
      modifying it, the result is undefined.

      The most immediate solution is to use a copy of the list you iterate over :
      >>[169]: A = range(1,27)
      >>>[170]: B = range(1,27)
      >>>[171]: for b in B[:] :
      if b*b in A:
      print b
      else:
      B.remove(b)
      .....:
      .....:
      1
      2
      3
      4
      5
      >>>[176]: B
      ...[176]: [1, 2, 3, 4, 5]

      Note that this can be easily done with the simpler :

      B = [ e for e in B if e*e not in A ]

      --
      _____________

      Maric Michaud

      Comment

      • ToshiBoy

        #4
        Re: this is simple...

        On Jun 28, 2:48 pm, Mel <mwil...@the-wire.comwrote:
        ToshiBoy wrote:
        I have two lists A and B that are both defined as range(1,27) I want
        to find the entries that are valid for A = BxB
        [ ... ]
        I get, as expected 1,4,9,16,25 printed out being the only members of B
        where the condition is true, but when I print B I get:
        >
        [1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]
        >
        1 to 5 is correct, but why doesn't the remove method remove 7 and
        above? What am I doing wrong here?
        >
        Try this:
        >
        A = range(1,27)
        B = range(1,27)
        C = []
        >
        for b in B:
            print "Trying", b
            if b*b in A:
                print b
                C.append (b)
            else:
                print "Removing", b
                B.remove(b)
        print 'B', B
        print 'C', C
        >
        The essential problem is that your `B.remove`s are pulling the rug out from
        under your `for b in B:`.  There are ways to mess with B while you iterate.
        Running though B backwards will do: `for b in B[::-1]:`, or iterating over
        a copy of B: `for b in B[:]:` or `for b in list(B):`.  Leaving B alone and
        building up the desired items in C is probably simplest.
        >
                Mel.
        Thank you, of course! :-) Didn't even think of that... that I was
        modifying my iterators...

        Thank you

        Comment

        Working...