list mutability

Discussion in 'Python' started by gigs, Feb 18, 2008.

  1. gigs

    gigs Guest

    hi im having this code

    l = [1, 3, 5, 'D', 1, 2, 3, 4, 5, 6, 7, 'A', 'S', 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 'A']

    why i need to copy x list? can someone explain me. If i dont copy it i get this
    result:
    >>> took_num_range(l)

    [[1, 2, 3, 4, 5, 6, 7], [6, 5, 4, 3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0], [6, 5, 4,
    3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0]]

    but if i copy it i get result as im looking for
    >>> took_num_range(l)

    [[1, 2, 3, 4, 5, 6, 7], [9, 8, 7, 6, 5, 4, 3], [8, 7, 6, 5, 4, 3, 2], [7, 6, 5,
    4, 3, 2, 1], [6, 5, 4, 3, 2, 1, 0]]
    >>>


    def took_num_range(l):
    j = []
    x = []
    for i in l:
    if type(i) is int and len(x) == 7:
    j.append(x)
    x = x[:] # im mean here
    x.pop(0)
    if type(i) is int and len(x) < 7:
    x.append(i)
    if type(i) is not int and len(x) == 7:
    j.append(x)
    x = []
    if type(i) is not int and len(x) != 7:
    x = []
    return j


    thx
     
    gigs, Feb 18, 2008
    #1
    1. Advertising

  2. gigs

    John Machin Guest

    On Feb 19, 5:09 am, gigs <-com.hr> wrote:
    > hi im having this code
    >
    > l = [1, 3, 5, 'D', 1, 2, 3, 4, 5, 6, 7, 'A', 'S', 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 'A']
    >
    > why i need to copy x list? can someone explain me. If i dont copy it i get this
    > result:
    > >>> took_num_range(l)

    > [[1, 2, 3, 4, 5, 6, 7], [6, 5, 4, 3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0], [6, 5, 4,
    > 3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0]]
    >
    > but if i copy it i get result as im looking for
    > >>> took_num_range(l)

    > [[1, 2, 3, 4, 5, 6, 7], [9, 8, 7, 6, 5, 4, 3], [8, 7, 6, 5, 4, 3, 2], [7, 6, 5,
    > 4, 3, 2, 1], [6, 5, 4, 3, 2, 1, 0]]
    > >>>

    >
    > def took_num_range(l):
    > j = []
    > x = []
    > for i in l:
    > if type(i) is int and len(x) == 7:
    > j.append(x)
    > x = x[:] # im mean here
    > x.pop(0)


    j.append(x) saves a reference to the same list that x refers to. So
    when you later mutate that one list, all references in j refer to the
    mutated list.

    Instead of
    x = x[:]
    x.pop(0)
    which copies the contents twice, you can do
    x = x[1:]

    In a more complicated example, it would be better to take a copy at
    each point:

    j.append(x[:])

    .... then you are sure you have a photo of x and it doesn't matter how/
    when you mutate x later.

    > if type(i) is int and len(x) < 7:


    This is a big trap for the casual reader (len(x) may have changed
    since the previous "if" statement) ... see below.

    > x.append(i)
    > if type(i) is not int and len(x) == 7:
    > j.append(x)
    > x = []
    > if type(i) is not int and len(x) != 7:
    > x = []


    What do you want to do if your input ends with 7 integers and no
    letter, e.g.
    [1,2,3,'A',1,2,3,4,5,6,7]
    ?

    > return j


    Some suggestions:
    1. use meaningful names
    2. don't have hard-wired numbers like 7
    3. use "else" and "elif" as appropriate to avoid repeating conditions
    unnecessarily.

    Here's a suggested replacement for your code, tested to the extent
    shown:

    C:\junk>type tooknumrange.py
    def took_num_range(seq, size, grab_end=False):
    result = []
    queue = []
    for item in seq:
    if isinstance(item, int):
    if len(queue) == size:
    result.append(queue)
    queue = queue[1:]
    queue.append(item)
    else:
    if len(queue) == size:
    result.append(queue)
    queue = []
    if grab_end and len(queue) == size:
    result.append(queue)
    return result

    test1 = [
    1, 3, 5, 'D',
    1, 2, 3, 4, 5, 6, 7, 'A',
    'S',
    9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 'A',
    ]
    test1r = [
    [1, 2, 3, 4, 5, 6, 7],
    [9, 8, 7, 6, 5, 4, 3],
    [8, 7, 6, 5, 4, 3, 2],
    [7, 6, 5, 4, 3, 2, 1],
    [6, 5, 4, 3, 2, 1, 0],
    ]
    test2 = [1, 2, 3, 4, 5]
    test2r = [[1, 2, 3, 4, 5]] ### or is it [] ???
    tests = [
    (test1, test1r, 7, False),
    (test2, [], 5, False),
    (test2, test2r, 5, True),
    ]

    failed = 0
    for tno, (tseq, tresult, tsize, tgrab) in enumerate(tests):
    aresult = took_num_range(tseq, tsize, grab_end=tgrab)
    if aresult != tresult:
    failed += 1
    print 'Test %d failed' % (tno+1)
    print 'Expected:', tresult
    print 'Actual :', aresult
    print 'Failed %d test(s) out of %d' % (failed, len(tests))


    C:\junk>tooknumrange.py
    Failed 0 test(s) out of 3

    HTH,
    John
     
    John Machin, Feb 18, 2008
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Edward C. Jones

    Mutability problem when subclassing tuple

    Edward C. Jones, Feb 19, 2004, in forum: Python
    Replies:
    2
    Views:
    599
    Shalabh Chaturvedi
    Feb 19, 2004
  2. ex_ottoyuhr

    Mutability of function arguments?

    ex_ottoyuhr, Dec 8, 2005, in forum: Python
    Replies:
    17
    Views:
    472
    Fredrik Lundh
    Dec 8, 2005
  3. named tuple mutability

    , May 14, 2008, in forum: Python
    Replies:
    10
    Views:
    451
    Bruno Desthuilliers
    May 15, 2008
  4. cnb
    Replies:
    1
    Views:
    215
    Alan G Isaac
    Aug 26, 2008
  5. kj
    Replies:
    4
    Views:
    414
    Arnaud Delobelle
    Oct 7, 2010
Loading...

Share This Page