-1

I have one function that calls for the function rlEncode which is supposed to take the data list and compress it so it counts how many values in a row there are and would output for example [1, 5, 3, 2, 5, 6] and so on. But when I run it just out puts the [1,5] again and again and not moving the n value over however so many spaces in the list. How would I get the n value from the function rlEncode to be used in the other function?

def rlEncode(n, z, data_list):
    while data_list[n] == data_list[n+1]:
        z = z + 1
        n = n + 1
    while data_list[n] != data_list[n+1]:
        return n
        return z

def unitTest( ):
    c = 0
    n = 0
    z = 1
    data_list = [1,1,1,1,1,3,3,5,5,5,5,5,5,6,8,8,1,1,1,5,5,5,5,13,14, 14]
    compress_list = [ ]
    while c < (len(data_list)):
        
        n = rlEncode(n, 1, data_list)
        z = rlEncode(0, z, data_list)
        rlEncode(0, 1, data_list)

        
        compress = [data_list[n], z]
       
        c = c + 1
        compress_list = compress_list + compress
        print(compress_list)

        n = n+1
yeezy
  • 5
  • 3
  • Why are you passing 'list_name' into rlEncode and then not using it? Instead you are using a global variable. With 'compress' you have both a global variable and a local one. You are modifying the local one and then throwing it away, but expecting the global one to be changed. Advice: Re-work the entire thing to **not** use global variables. – RobertB Oct 20 '15 at 21:55

2 Answers2

1

Python passes immutable objects by value. See this previous answer: How do I pass a variable by reference?

The simplest solution in your case is to have the inner function return the value of n to the outer function, which assigns it to its local n.

compress is a list, which is mutable, so you can use += to mutate the list in place rather than creating a new local variable.

I also added a check against the list length, otherwise the references to n+1 will cause IndexError.

I also don't think you need the second while loop in rlEncode but I'll leave that up to you to sort out... :)

def rlEncode(n, z, data_list, compress):
    while (n < len(data_list)-1) and (data_list[n] == data_list[n+1]):
        z = z + 1
        n = n + 1
    while (n < len(data_list)-1) and (data_list[n] != data_list[n+1]):
        compress += [data_list[n], z]
        n = n + 1
    return n

def unitTest(data_list):
    c = 0
    n = 0
    compress = []
    while c < (len(data_list)):
        n = rlEncode(n, 1, data_list, compress)
        c = c + 1
    return ('list: ', data_list, "compressed list: ", compress)

sample_data = [1,1,1,1,1,3,3,5,5,5,5,5,5,6,8,8,1,1,1,5,5,5,5,13, 14, 14]
unitTest(sample_data)
Community
  • 1
  • 1
coder123
  • 61
  • 1
  • 3
  • Thank you. Would I do the same thing for compress so I could compile all of them into one big list? – yeezy Oct 20 '15 at 21:56
  • compress is a list, which is a mutable object, so you can use += to add the list to itself rather than creating a new local variable. As RobertB noted, there's also a typo in your example, I'm guessing from a variable name change. I'll update my answer. – coder123 Oct 20 '15 at 22:01
  • i changed it to where I am at now. For some reason the z isn't outputting right and keeps getting 4. Would you mine looking at where i am going wrong? Thanks – yeezy Oct 20 '15 at 22:50
0

I like doing these things recursively. Python isn't great with recursion but I wanted to see how it's done so I guess I'll share:

def compress(lst):
    if not lst:
        return []
    current = lst[0]
    result = compress(lst[1:]) 

    if not result:
        # item is last
        return [(1, current)]
    nxt = result[0][1]

    if current == nxt:
        # items is same as next
        return [(result[0][0] + 1, current)] + result[1:]

    # different items
    return [(1, current)] + result

To use it:

print [x[0] for x in compress(lst)]

The obvious and efficient way would be a generator:

def group_gen(lst):
    buff = []
    for item in lst:
        if buff and item == buff[0]:
            buff.append(item)
        else:
            if buff:
                yield buff
            buff = [item]
    if buff:
        yield buff

print list(map(len, group_gen(lst)))

Check it using:

print list(map(len, group_gen(lst)))
Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88