I have a dictionary of the form:
{"level":[1,2,3], "conf":[-1,1,2], "text":["here","hel","llo"]}
I want to filter the lists to remove every item at index i
, where "conf"
at index i
is not >0.
So for example if I have an input like this:
{"level":[1,2,3], "conf":[-1,1,2], "text":["here","hel","llo"]}
The output should be this:
{"level":[2,3], "conf":[1,2],text:["hel","llo"]}
as the first value of conf
was not > 0.
I have tried something like this:
new_dict = {i: [a for a in j if a >= min_conf] for i, j in my_dict.items()}
But that would work just for one key.
REPLY: Lot of good solutions below. I just thought about another one.
- Turn this dict of list structure into a list of tuple:
tuples =[(1,-1,"here"), (2, 1, "hel"),(3,"2","llo")]
- then I just have to filter this list by the 2nd item of each tuple which is quite easy:
filter(lambda item: item[1] >= 0, tuples)
CodePudding user response:
I would keep the indexes of valid elements (those greater than 0) with:
kept_keys = [i for i in range(len(my_dict['conf'])) if my_dict['conf'][i] > 0]
And then you can filter each list checking if the index of a certain element in the list is contained in kept_keys
:
{k: list(map(lambda x: x[1], filter(lambda x: x[0] in kept_keys, enumerate(my_dict[k])))) for k in my_dict}
Output:
{'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']}
CodePudding user response:
try:
from operator import itemgetter
def filter_dictionary(d):
conf = d['conf']
positive_indices = [i for i, item in enumerate(conf) if item > 0]
f = itemgetter(*positive_indices)
return {k: list(f(v)) for k, v in d.items()}
d = {"level": [1, 2, 3], "conf": [-1, 1, 2], "text": ["-1", "hel", "llo"]}
print(filter_dictionary(d))
output:
{'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']}
I tried to first see which indices of 'conf'
are positive, then with itemgetter
I picked those indices from values inside the dictionary.
CodePudding user response:
I solved it with this:
from typing import Dict, List, Any, Set
d = {"level":[1,2,3], "conf":[-1,1,2], "text":["-1","hel","llo"]}
filtered_indexes = set([i for i in range(len(d.get('conf', []))) if d.get('conf')[i] > 0])
def filter_dictionary(d: Dict[str, List[Any]], filtered_indexes: Set[int]) -> Dict[str, List[Any]]:
for key, list_values in d.items():
d[key] = [value for i, value in enumerate(list_values) if i in filtered_indexes]
return d
print(filter_dictionary(d, filtered_indexes))
Output:
{'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']}
CodePudding user response:
a = {"level":[1,2,3], "conf":[-1,1,2],"text":["-1","hel","llo"]}
for k, v in a.items():
if k == "conf":
for element in v:
if element < 0:
to_delete = [] #it will store the index numbers of the conf that you want to delete(conf<0)
to_delete.append(v.index(element))
for position in to_delete:
for k, v in a.items():
v.pop(position)
and then a will be {'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']} which is what you want.
CodePudding user response:
You can have a function which works out which indexes to keep and reformulate each list with only those indexes:
my_dict = {"level":[1,2,3], "conf":[-1,1,2],'text':["-1","hel","llo"]}
def remove_corresponding_items(d, key):
keep_indexes = [idx for idx, value in enumerate(d[key]) if value>0]
for key, lst in d.items():
d[key] = [lst[idx] for idx in keep_indexes]
remove_corresponding_items(my_dict, 'conf')
print(my_dict)
Output as requested
CodePudding user response:
Lots of good answers. Here's another 2-pass approach:
mydict = {"level": [1, 2, 3], "conf": [-1, 1, 2], 'text': ["-1", "hel", "llo"]}
for i, v in enumerate(mydict['conf']):
if v <= 0:
for key in mydict.keys():
mydict[key][i] = None
for key in mydict.keys():
mydict[key] = [v for v in mydict[key] if v]
print(mydict)
Output:
{'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']}
CodePudding user response:
I believe this will work:
d = {"level":[1,2,3], "conf":[-1,1,2], "text":["-1","hel","llo"]}
for key in d:
if key != "conf":
d[key] = [d[key][i] for i in range(len(d[key])) if d["conf"][i] >= 0]
d["conf"] = [i for i in d["conf"] if i>=0]
print(d)
Output:
{'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']}
CodePudding user response:
Try this:
a_dict = {"level": [1, 2, 3], "conf": [-1, 1, 2], "text": ["-1", "hel", "llo"]}
for a_list in a_dict.values():
print(a_list)
iterations = 0
for item in a_list[::-1]:
if iterations >= 2:
a_list.remove(item)
iterations = 1
print(a_dict)
Output:
{'level': [2, 3], 'conf': [1, 2], 'text': ['hel', 'llo']}