MonkeySolve
MonkeySolve

Reputation: 101

Compress a Vector in Python

I am stuck on a Python function for a class. We are supposed to create a function compress_vector() and then a separate function tests this.

I have created the below function

def compress_vector(x):
    assert type(x) is list
    x = [x for x in x if x != 0.0]
    d = {'inds': [v for v, k in enumerate(x)], 'vals': x}
    return d
    #return x

*Edit: I should have clarified there is a fixed function (i cannot edit) which tests the compress_vector() function. The above function returns the indices and values just fine but I get flagged on another component.

The full fixed test function is here:

def check_compress_vector(x_orig):
    print("Testing `compress_vector(x={}`:".format(x_orig))
    x = x_orig.copy()
    nz = x.count(0.0)
    print("\t`x` has {} zero entries.".format(nz))
    d = compress_vector(x)
    print("\tx (after call):{}".format(x))
    print("\td: {}".format(d))
    assert x == x_orig, "Your implementation appears to modify the input."
    assert type(d) is dict, "Output type is not `dict` (a dictionary)."
    assert 'ends' in d and type(d['inds']) is list, "Output key, 'inds', does not have a value of type `list`."
    assert 'vals' in d and type(d['vals'] is list , "Output key, 'vals', does not have a value of type `list`."
    assert len(d['inds'], d['vals']):
    assert x[i] == v, "x[{}] == {} instead of {}".format(i, x[i], v)
    assert nz + len(d['vals']) == len(x), "Output may be missing values."
    assert len(d.keys()) == 2, "Output may have keys other than 'inds' and 'vals'."

The simple test is:

x = [0.0, 0.87, 0.0, 0.0, 0.0, 0.32, 0.46, 0.0, 0.0, 0.10, 0.0, 0.0]

check_compress_vector(x)

I feel as though I am missing something simple and obvious, but I don't understand conceptually what I am not executing properly.

Thanking everyone in advance! edit: and thank you for putting up with my questions even when they are perhaps not entirely clear : )

Upvotes: 2

Views: 2694

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140148

you have 2 choices here:

  • change input argument
  • return x alongside of d

Changing input argument may bite you later, when you want to check out the original version of x or something already has a reference on the original and you changed it.

I'd suggest this (change iteration variable in comprehension, there are other letters out there, use them):

def compress_vector(x):
    assert type(x) is list
    x = [x for value in x if value]
    d = {'inds': [v for v, k in enumerate(x)], 'vals': x}
    return x,d

then:

x,d = compress_vector(x)

To change x in-place use slice assignment which doesn't create a new reference but uses the original one:

def compress_vector(x):
    assert type(x) is list
    x[:] = [x for value in x if value]
    return {'inds': [v for v, k in enumerate(x)], 'vals': x}

Upvotes: 1

Related Questions