I tried to find the solution everywhere but I couldn't find the way to solve this problem. Suppose I have multiple dictionaries in a list:
[
{"Type": "A", "Name": "Sam"},
{"Type": "A", "Name": "Apple"},
{"Type": "B", "Name": "Sam"},
{"Type": "C", "Name": "Apple"},
{"Type": "C"}
]
What I need are the dictionaries that have 'Type' == 'A'.
The result I am trying to get is:
[{"Type": "A", "Name": "Sam"}, {"Type": "A", "Name": "Apple"}]
Is there any way I could achieve this? Any help or any direction into solving this problem would be great.
Go through your list and take all dictionaries with a Type of A:
>>> data = [{"Type": "A", "Name": "Sam"},{"Type":"A", "Name":"Apple"},{"Type": "B", "Name": "Sam"},{"Type":"C", "Name":"Apple"},{"Type":"C"}]
>>> [d for d in data if d.get('Type') == 'A']
[{'Name': 'Sam', 'Type': 'A'}, {'Name': 'Apple', 'Type': 'A'}]
Using dict.get() ensures that it works for dicts without the key Type:
data = [{"Type": "A", "Name": "Sam"},
{"Type":"A", "Name":"Apple"},
{"Type": "B", "Name": "Sam"},
{"Type":"C", "Name":"Apple"},
{"Type":"C"},
{}]
>>> [d for d in data if d.get('Type') == 'A']
[{'Name': 'Sam', 'Type': 'A'}, {'Name': 'Apple', 'Type': 'A'}]
because:
get(key[, default])
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.
>>> a
[{'Type': 'A', 'Name': 'Sam'}, {'Type': 'A', 'Name': 'Apple'}, {'Type': 'B', 'Name': 'Sam'}, {'Type': 'C', 'Name': 'Apple'}, {'Type': 'C'}]
>>> b = [x for x in a if x['Type']=='A']
>>> b
[{'Type': 'A', 'Name': 'Sam'}, {'Type': 'A', 'Name': 'Apple'}]
[d for d in d_list if d.get('Type') == 'A']
This is almost definitely not the most pythonic way of doing it, but if you need a quick and dirty solution, I believe it works.
def filterDictionaries(dictionaries, type):
filteredDicts = []
for dict in dictionaries:
if 'Type' in dict:
if dict['Type] == type:
filteredDicts += dict
return filteredDicts
Related
I have dictionary like that:
dic={'61': {'NAME': 'John', 'LASTNAME': 'X', 'EMAIL': 'X#example.com', 'GRADE': '99'}, '52': {'NAME': 'Jennifer', 'LASTNAME': 'Y', 'EMAIL': 'Y#example.com', 'GRADE': '98'}}
obj = json.dumps(dic,indent=3)
print(obj)
I want to create Json for some values.
{
"NAME": "John",
"LASTNAME": "X",
,
"NAME": "Jennifer",
"LASTNAME": "Y"
}
Any idea for help?
If I understand correctly you want to keep the values of your original data without the indices and also filter out some of them (keep only "NAME" and "LASTNAME"). You can do so by using a combination of dictionary and list comprehensions:
array = [{k:v for k,v in d.items()if k in ("NAME","LASTNAME")} for d in dic.values()]
This creates the following output:
>>> array
[{'NAME': 'John', 'LASTNAME': 'X'}, {'NAME': 'Jennifer', 'LASTNAME': 'Y'}]
a =[{
"id":"1",
"Name":'BK',
"Age":'56'
},
{
"id":"1",
"Sex":'Male'
},
{
"id":"2",
"Name":"AK",
"Age":"32"
}]
I have a list of dictionary with a person information split in multiple dictionary as above for ex above id 1's information is contained in first 2 dictionary , how can i get an output of below
{1: {'Name':'BK','Age':'56','Sex':'Male'}, 2: { 'Name': 'AK','Age':'32'}}
You can use a defaultdict to collect the results.
from collections import defaultdict
a =[{ "id":"1", "Name":'BK', "Age":'56' }, { "id":"1", "Sex":'Male' }, { "id":"2", "Name":"AK", "Age":"32" }]
results = defaultdict(dict)
key = lambda d: d['id']
for a_dict in a:
results[a_dict.pop('id')].update(a_dict)
This gives you:
>>> results
defaultdict(<class 'dict'>, {'1': {'Name': 'BK', 'Age': '56', 'Sex': 'Male'}, '2': {'Name': 'AK', 'Age': '32'}})
The defaultdict type behaves like a normal dict, except that when you reference an unknown value, a default value is returned. This means that as the dicts in a are iterated over, the values (except for id) are updated onto either an existing dict, or an automatic newly created one.
How does collections.defaultdict work?
Using defaultdict
from collections import defaultdict
a = [{
"id": "1",
"Name": 'BK',
"Age": '56'
},
{
"id": "1",
"Sex": 'Male'
},
{
"id": "2",
"Name": "AK",
"Age": "32"
}
]
final_ = defaultdict(dict)
for row in a:
final_[row.pop('id')].update(row)
print(final_)
defaultdict(<class 'dict'>, {'1': {'Name': 'BK', 'Age': '56', 'Sex': 'Male'}, '2': {'Name': 'AK', 'Age': '32'}})
You can combine 2 dictionaries by using the .update() function
dict_a = { "id":"1", "Name":'BK', "Age":'56' }
dict_b = { "id":"1", "Sex":'Male' }
dict_a.update(dict_b) # {'Age': '56', 'Name': 'BK', 'Sex': 'Male', 'id': '1'}
Since the output the you want is in dictionary form
combined_dict = {}
for item in a:
id = item.pop("id") # pop() remove the id key from item and return the value
if id in combined_dict:
combined_dict[id].update(item)
else:
combined_dict[id] = item
print(combined_dict) # {'1': {'Name': 'BK', 'Age': '56', 'Sex': 'Male'}, '2': {'Name': 'AK', 'Age': '32'}}
from collections import defaultdict
result = defaultdict(dict)
a =[{ "id":"1", "Name":'BK', "Age":'56' }, { "id":"1", "Sex":'Male' }, { "id":"2", "Name":"AK", "Age":"32" }]
for b in a:
result[b['id']].update(b)
print(result)
d = {}
for p in a:
id = p["id"]
if id not in d.keys():
d[id] = p
else:
d[id] = {**d[id], **p}
d is the result dictionary you want.
In the for loop, if you encounter an id for the first time, you just store the incomplete value.
If the id is in the existing keys, update it.
The combination happens in {**d[id], **p}
where ** is unpacking the dict.
It unpacks the existing incomplete dict associated withe the id and the current dict, then combine them into a new dict.
There are two lists:
customer_list = ["A7", "A8", "A9", "A10", "A11"]
customer_index = ["8", "9", "10", "11", "12"]
The goal is to create the following:
final_list = [
{
"kind": "report#variable",
"type": "A7",
"value": line[8]}
,
{
"kind": "report#variable",
"type": "A8",
"value": line[9]}
,
{
"kind": "report#variable",
"type": "A9",
"value": line[10]}
,
{
"kind": "report#variable",
"type": "A10",
"value": line[11]}
,
{
"kind": "report#variable",
"type": "A11",
"value": line[12]}
]
I tried to use the following Python code, but it did not work:
def create_final_list(list_1, list_2):
new_list = []
list_prefix = '{"kind": "report#variable",'
for num in list_1:
for val in list_2:
list_1_num = ' "type": ' + num
list_2_val = ' "value": ' + val
new_list.append(list_prefix + list_1_num + list_2_val)
return new_list
How does one automatically create a list of Dictionaries based upon two lists of equal length and the desired format as in the above example?
This is not a JSON; but a list of dictionaries which you create in a list-comprehension with zip():
customer_list = ["A7", "A8", "A9", "A10", "A11"]
customer_index = ["8", "9", "10", "11", "12"]
line = [1,2,3,4,5,6,7,8,9,101,11,12,13,14] # assume this `line` list
res = [{"kind": "report#variable", "type": x, "value": line[int(y)]} for x, y in zip(customer_list, customer_index)]
As is in the comments, you can then do:
json.dumps(res)
..to convert res to a JSON string.
Since pandas is tagged, adding another way using a dataframe and groupby:
df = pd.DataFrame({"kind": "report#variable","type":customer_list,"value":customer_index})
final = [g.droplevel(0).to_dict() for _,g in df.stack().groupby(level=0)]
[{'kind': 'report#variable', 'type': 'A7', 'value': '8'},
{'kind': 'report#variable', 'type': 'A8', 'value': '9'},
{'kind': 'report#variable', 'type': 'A9', 'value': '10'},
{'kind': 'report#variable', 'type': 'A10', 'value': '11'},
{'kind': 'report#variable', 'type': 'A11', 'value': '12'}]
Try
lis = []
for i in range(len(customer_index)):
dic = {"type" : customer_list[i], "value" : customer_index[i]}
lis.append(dic)
This outputs
[{'type': 'A7', 'value': '8'},
{'type': 'A8', 'value': '9'},
{'type': 'A9', 'value': '10'},
{'type': 'A10', 'value': '11'},
{'type': 'A11', 'value': '12'}]
As in your code, if you want line[8], do line[customer_index[i]] instead of customer_index[i] during dictionary initialization. Also, add 1 more key of kind in the dictionary, as per your requirement.
The above code works only if both customer_list and customer_index are of equal length, because the loop iterates n number of times, where n is the equal length of the list.
I have a tree-structure separated by tabs and lines like this:
a
\t1
\t2
\t3
\t\tb
\t\tc
\t4
\t5
And I am looking to turn this into:
{
'name': 'a',
'children': [
{'name': '1'},
{'name': '2'},
{
'name': '3'
'children': [
{'name': 'b'},
{'name': 'c'}
]
},
{'name': '4'},
{'name': '5'}
]
}
for a d3.js collapsible tree data input. I am assuming I have to use recursion in some way but I cannot figure out how.
I have tried turning the input into a list like this:
[('a',0), ('1',1), ('2',1), ('3',1), ('b',2), ('c',2), ('4',1), ('5',1)]
using this code:
def parser():
#run from root `retail-tree`: `python3 src/main.py`
l, all_line_details = list(), list()
with open('assets/retail') as f:
for line in f:
line = line.rstrip('\n ')
splitline = line.split(' ')
tup = (splitline[-1], len(splitline)-1)
l.append(splitline)
all_line_details.append(tup)
print(tup)
return all_line_details
Here, the first element is the string itself and the second is the number of tabs there are in that line. Unsure of the recursion step to accomplish this. Appreciate any help!
You can use a function that uses re.findall with a regex that matches a line as the name of the node, followed by 0 or more lines that start with a tab, grouped as the children, and then recursively builds the same structure for the children after stripping the first tab of each line from the children string:
import re
def parser(s):
output = []
for name, children in re.findall(r'(.*)\n((?:\t.*\n)*)', s):
node = {'name': name}
if children:
node.update({'children': parser(''.join(line[1:] for line in children.splitlines(True)))})
output.append(node)
return output
so that given:
s = '''a
\t1
\t2
\t3
\t\tb
\t\tc
\t4
\t5
'''
parser(s)[0] returns:
{'name': 'a',
'children': [{'name': '1'},
{'name': '2'},
{'name': '3', 'children': [{'name': 'b'}, {'name': 'c'}]},
{'name': '4'},
{'name': '5'}]}
Working from the list structure you provided from your own parser function:
def make_tree(lines, tab_count=0):
tree = []
index = 0
while index < len(lines):
if lines[index][1] == tab_count:
node = {"name": lines[index][0]}
children, lines_read = make_tree(lines[index + 1:], tab_count + 1)
if children:
node["children"] = children
index += lines_read
tree.append(node)
else:
break
index += 1
return tree, index
Test cases:
lines = [("a", 0), ("1", 1), ("2", 1), ("3", 1), ("b", 2), ("c", 2), ("4", 1), ("5", 1)]
test_1 = make_tree([("a", 0)])
assert test_1[0] == [{"name": "a"}], test_1
test_2 = make_tree([("a", 0), ("b", 1)])
assert test_2[0] == [{"name": "a", "children": [{"name": "b"}]}], test_2
test_3 = make_tree(lines)
expected_3 = [
{
"name": "a",
"children": [
{"name": "1"},
{"name": "2"},
{"name": "3", "children": [{"name": "b"}, {"name": "c"}]},
{"name": "4"},
{"name": "5"},
],
}
]
assert test_3[0] == expected_3, test_3
Note the output is wrapped in a list in case your source file has more than one root node (i.e. more than one line with no leading tabs), and also for neatness of the recursion.
I'm trying to create what I think is a 'projection' from a larger dictionary space onto a smaller dimension space. So, if I have:
mine = [
{"name": "Al", "age": 10},
{"name": "Bert", "age": 15},
{"name": "Charles", "age": 17}
]
I'm trying to find a functional expression to return only:
[
{"name": "Al"},
{"name": "Bert"},
{"name": "Charles"}
]
I've tried...
>>> filter(lambda x: x['name'],mine)
[{'age': 10, 'name': 'Al'}, {'age': 15, 'name': 'Bert'}, {'age': 17, 'name': 'Charles'}]
>>> map(lambda x : x['name'],mine)
['Al', 'Bert', 'Charles']
But seem to still be missing the right function. I know how to do it with a list comprehension, but would like to do learn how to do this functionally.
Sounds like a job for list comprehensions, whether you like them or not.
>>> [{"name": d["name"]} for d in mine]
[{'name': 'Al'}, {'name': 'Bert'}, {'name': 'Charles'}]
The solution without a list comprehension would require an additional function definition:
def project(key, d):
return {k: d[k]}
map(partial(project, "name"), mine)
Or a lambda (yuck):
map(lambda d: {"name": d["name"]}, mine)
CODE:
print([{'name': d['name']} for d in mine])
OUTPUT:
[{'name': 'Al'}, {'name': 'Bert'}, {'name': 'Charles'}]
In case we want to preserve more than one key:
input_dicts = [
{"name": "Al", "age": 40, "level": "junior"},
{"name": "Bert", "age": 30, "level": "mid"},
{"name": "Charles", "age": 20, "level": "senior"}
]
selected_keys = ("name", "level")
[
{key: value for key, value in a_dict.items() if key in selected_keys}
for a_dict in input_dicts
]
[{'name': 'Al', 'level': 'junior'},
{'name': 'Bert', 'level': 'mid'},
{'name': 'Charles', 'level': 'senior'}]