I have a very long dictionary
mydict = {
"6574": [],
"3234": [1],
"7014": [],
"0355": [3],
"1144": [2],
# …
}
I need to get all keys that have a non-empty list.
mytruedict = {}
for k, v in mydict.items():
if v:
mytruedict[k]=v
I was wondering if there is a one-line approach to it.
Using dict
Ex:
mydict = {
"6574": [],
"3234": [1],
"7014": [],
"0355": [3],
"1144": [2]
}
print( dict((k, v) for k, v in mydict.items() if v) )
#or
print( {k: v for k, v in mydict.items() if v } ) #dict comprehension
Output:
{'3234': [1], '1144': [2], '0355': [3]}
Related
In the below program, I am trying to add all my "new_list" values into my "fin_list". But append is not working as excpected and is overwriting it with whatever the "new_list"value is in that particular loop.
def all_subsequences(ind, a, new_list, fin_list):
if(ind >= len(a)):
print(new_list)
fin_list.append(new_list)
return
new_list.append(a[ind])
all_subsequences(ind+1, a, new_list, fin_list)
#new_list.remove(new_list[len(new_list)-1])
new_list.pop()
all_subsequences(ind+1, a, new_list, fin_list)
return fin_list
a = [3,1,2]
new_list = []
final_list = []
result = all_subsequences(0, a, new_list, final_list)
print(result)
Here the output at each level is as below
[3, 1, 2], [3, 1], [3, 2], [3], [1, 2], [1], [2], []
Since the last value is an empty list the final list value at the last is as below
[[], [], [], [], [], [], [], []]
Link to python sandbox :-
https://pythonsandbox.com/code/pythonsandbox_u21270_9PqNjYIsl7M85NGf4GBSLLrW_v0.py
I have tried to use extend instead of append inside the base condition but that is not the kind of result i am looking for. I am open to any suggestion to resolve this problem.
When you call fin_list.append(new_list), you are appending the reference of new_list to fin_list instead of copying fin_list. Therefore, when you do new_list.pop() later, if you print fin_list, you will find it's also changed.
The situation can be illustrated by this example:
foo = [1, 2, 3]
bar = []
bar.append(foo)
print(f"bar: {bar}")
# modify foo and you will find that bar is also modified
foo.append(4)
print(f"bar: {bar}")
The simplest way to solve the problem is to use fin_list.append(new_list[:]), which will copy new_list and append the copy to fin_list.
def all_subsequences(ind, a, new_list, fin_list):
if (ind >= len(a)):
print(new_list)
fin_list.append(new_list[:])
return
new_list.append(a[ind])
all_subsequences(ind+1, a, new_list, fin_list)
new_list.pop()
all_subsequences(ind+1, a, new_list, fin_list)
return fin_list
a = [3, 1, 2]
new_list = []
final_list = []
result = all_subsequences(0, a, new_list, final_list)
print(result)
dictionary = {"raj": 2, "striver": 3, "vikram": 4}
myvals = [2,4]
Need to get ['raj', 'vikram'] as a list filtering above dictionary using myvals list
tried
result = [dictionary[k] for k in [2, 4]]
result = [dictionary[k] for k in myvals]
[k for k, v in dictionary.items() if v in myvals]
I have the following for instance:
x = [{'A':1},{'A':1},{'A':2},{'B':1},{'B':1},{'B':2},{'B':3},{'C':1},{'D':1}]
and I would like to get a dictionary like this:
x = [{'A': [1,2], 'B': [1,2,3], 'C':[1], 'D': [1]}]
Do you have any idea how I could get this please?
You could use a collections.defaultdict of sets to collect unique values, then convert the final result to a dictionary with values as lists using a dict comprehension:
from collections import defaultdict
lst = [{'A':1},{'A':1},{'A':2},{'B':1},{'B':1},{'B':2},{'B':3},{'C':1},{'D':1}]
result = defaultdict(set)
for dic in lst:
for key, value in dic.items():
result[key].add(value)
print({key: list(value) for key, value in result.items()})
Output:
{'A': [1, 2], 'B': [1, 2, 3], 'C': [1], 'D': [1]}
Although its probably better to add your data directly to the defaultdict to begin with, instead of creating a list of singleton dictionaries(don't recommend this data structure) then converting the result.
Using dict.setdefault
Ex:
x = [{'A':1},{'A':1},{'A':2},{'B':1},{'B':1},{'B':2},{'B':3},{'C':1},{'D':1}]
res = {}
for i in x:
for k, v in i.items():
res.setdefault(k, set()).add(v)
#or res = [{k: list(v) for k, v in res.items()}]
print(res)
Output:
{'A': {1, 2}, 'B': {1, 2, 3}, 'C': {1}, 'D': {1}}
I need to replace the blank spaces or None values from this 2-d list
chess_board = [ [rook_3, knight_3, bishop_3, queen_2, king_2, bishop_4, knight_4, rook_4],
[pawn_9, pawn_10, pawn_11, pawn_12, pawn_13, pawn_14, pawn_15, pawn_16],
[],
[],
[],
[],
[pawn_1, pawn_2, pawn_3, pawn_4, pawn_5, pawn_6, pawn_7, pawn_8],
[rook_1, knight_1, bishop_1, queen_1, king_1, bishop_2, knight_2, rook_2]
]
Test for truthiness in a boolean context with a list comprehension:
[i for i in chess_board if i]
>>> x = [[1, 2], [], [3, 4]]
>>> [i for i in x if i]
[[1, 2], [3, 4]]
>>>
I need help with a function to flatten a nested dictionary in the following format:
dict_test = {
"subdoc": {
"a": 1,
"b": 2,
"c": 3,
"array": [
{"name": "elmo"},
{"name": "oscar"}
]
}
}
I tried the function below, but is doesn´t flatten the nested keys inside the array element.
def flatten_dict(dd, separator='.', prefix=''):
return { prefix + separator + k if prefix else k : v
for kk, vv in dd.items()
for k, v in flatten_dict(vv, separator, kk).items()
} if isinstance(dd, dict) else { prefix : dd }
My current output is:
{'subdoc.a': 1,
'subdoc.b': 2,
'subdoc.c': 3,
'subdoc.array': [{'name': 'elmo'}, {'name': 'oscar'}]}
But actually I´m looking something like:
{
"subdoc.a": 1,
"subdoc.b": 2,
"subdoc.c": 3,
"subdoc.array.0.name": "elmo",
"subdoc.array.1.name": "oscar"
}
dict_test = {
"subdoc": {
"a": 1,
"b": 2,
"c": 3,
"array": [
{"name": "elmo"},
{"name": "oscar"}
]
}
}
def flatten(d):
agg = {}
def _flatten(d, prev_key=''):
if isinstance(d, list):
for i, item in enumerate(d):
new_k = '%s.%s' % (prev_key, i) if prev_key else i
_flatten(item, prev_key=new_k)
elif isinstance(d, dict):
for k, v in d.items():
new_k = '%s.%s' % (prev_key, k) if prev_key else k
_flatten(v, prev_key=new_k)
else:
agg[prev_key] = d
_flatten(d)
return agg
print(flatten(dict_test))
# gives {'subdoc.a': 1, 'subdoc.b': 2, 'subdoc.c': 3, 'subdoc.array.0.name': 'elmo', 'subdoc.array.1.name': 'oscar'}
Note: only tested for your case