Reputation: 51
I have a python question:
Suppose you are given a vector, x
, containing real values that are mostly zero. For instance:
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]
Complete the function, compress_vector(x)
, so that returns a dictionary d
with two keys, d['inds']
and d['vals']
, which are lists that indicate the position and value of all the non-zero entries of x
. For the previous example,
d['inds'] = [1, 5, 6, 9]
d['vals'] = [0.87, 0.32, 0.46, 0.10]
Note 1. Your implementation must not modify the input vector x
.
Note 2. If x
contains only zero entries, d['inds']
and d['vals']
should be empty lists.
I was able to print the indices, but I'm not sure how to print the values.
def compress_vector(x):
assert type(x) is list
d = {'inds': [], 'vals': []}
d = ([i for i, e in enumerate(x) if e != 0], )
return d
Upvotes: 2
Views: 2074
Reputation: 4606
Soloution
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]
d = {"inds" : [], "vals" : []}
for i in range(len(x)):
if x[i] != 0:
d["inds"].append(i)
d["vals"].append(x[i])
for k, v in d.items():
print(str(k) + ": " + str(v))
Output
(xenial)vash@localhost:~/pcc/12/alien_invasion_2$ python3 help_print_value_list.py vals: [0.87, 0.32, 0.46, 0.1] inds: [1, 5, 6, 9] (xenial)vash@localhost:~/pcc/12/alien_invasion_2$
Comments
Just created some loops with conditions, if you have questions, comment.
Also this piece of code will help you match your "inds" to "vals" if ever needed, you can manipulate it as you like but just to get the idea through:
for i in range(len(d["inds"])):
print(str(d["inds"][i]) + ": " + str(d["vals"][i]))
This outputs:
(xenial)vash@localhost:~/pcc/12/alien_invasion_2$ python3 something.py 1: 0.87 5: 0.32 6: 0.46 9: 0.1 (xenial)vash@localhost:~/pcc/12/alien_invasion_2$
Upvotes: 0
Reputation: 20414
Filter out the zeroes from an enumerated x
and then use a dict-comprehension to extract the two elements from each tuple.
def compress_vector(x):
enumed = [(i,n) for i,n in enumerate(x) if n]
return {k:[e[i] for e in enumed] for i,k in enumerate(('inds','vals'))}
and a test:
>>> compress_vector(x)
{'inds': [1, 5, 6, 9], 'vals': [0.87, 0.32, 0.46, 0.1]}
Upvotes: 1
Reputation: 83527
You are very close. Let's look at one part of your code:
i, e in enumerate(x)
Here e
is the value from the list x
and i
is the index. So you can modify the list comprehension to
[e for i, e in enumerate(x) if e != 0]
^
Note that since this doesn't need the index, you can get rid of the enumerate()
call:
[e for e in x if e != 0]
You still need to make some modifications to store the two lists into a dictionary.
Upvotes: 2
Reputation: 79
What you are doing here is that you are assigning a tuple object to the dictionary object. Notice:
d = ([i for i, e in enumerate(x) if e != 0], )
The enclosing braces for the list comprehension make it a tuple. So you can't getd
to have this required represention:
d['inds'] = [1, 5, 6, 9]
d['vals'] = [0.87, 0.32, 0.46, 0.10]
You must explicitly append the values that satisfy the criteria to lists.
def compress_vector(x):
d = dict()
d['inds'] = []
d['vals'] = []
for i, e in enumerate(x):
if e != 0:
d['inds'].append(i)
d['vals'].append(e)
return d
If there are no non-zero values they won't be appended to the lists and you will get a dictionary with empty lists.
Upvotes: 0
Reputation: 670
This worked for me.
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]
def compress_vector(x):
d = {'inds': [], 'vals': []}
for i, val in enumerate(x):
if val != 0.0:
d['inds'].append(i)
d['vals'].append(val)
return d
d = compress_vector(x)
Upvotes: 0
Reputation: 69755
You can define this function as follows:
def compress_vector(x):
d = {'inds': [], 'vals': []}
for i, e in enumerate(x):
if e != 0:
d['inds'].append(i)
d['vals'].append(e)
return d
Basically, you create a dict
which values for 'inds'
and 'vals'
are initialized to the empty list. Then, you iterate the list using enumerate
in order to have the index (i
) and the element (e
). Inside the loop, you put the condition that the element should non-zero, and append i
and e
to the previous lists.
Upvotes: 4