I want to push two dictionaries into a list via for loop. I don't get why it is not working. Could you pls help? :)
result = {}
results = []
for i in range(count): # Count is 2, 2 different dictionaries
result.update({
'workitem_id': str(api_results[i]['workitem_id']),
'workitem_header': api_results[i]['workitem_header'],
'workitem_desc': api_results[i]['workitem_desc'],
'workitem_duration': str(api_results[i]['workitem_duration'])})
print(result) # Shows the two different dictionaries
results.append(result)
print(results) # Shows the list of two dictionaries, but the list contains the last dictionary for 2 times.
Output print(result): {Dictionary 1} , {Dictionary 2}
Output print(results): [{Dictionary 2} , {Dictionary 2}]
The expected output of print(results):
[{Dictionary 1}, {Dictionary 2}]
results = []
for i in range(count): #->Count is 2, 2 different dictionaries
result = {
'workitem_id' :str(api_results[i]['workitem_id']),
'workitem_header':api_results[i]['workitem_header'],
'workitem_desc':api_results[i]['workitem_desc'],
'workitem_duration':str(api_results[i] ['workitem_duration'])}
print(result)
results.append(result)
print(results)
During the second iteration, the .update method will update the first dictionary in the list. This is because it the two dictionary point to the same reference.
A similar example would be:
a = [1, 2, 3]
b = a
a[0] = 'this value is changed in b as well'
print(b)
#['this value is changed in b as well', 2, 3]
Is there any reason that we're not just using a more straightforward for loop?
results = []
for x in api_results:
result = {
'workitem_id': str(x['workitem_id']),
'workitem_header': x['workitem_header'],
'workitem_desc': x['workitem_desc'],
'workitem_duration': str(x['workitem_duration'])
}
results.append(result)
print(results)
You need to do something like
dictionaries = [ # Let this be the list of dictionaries you have (in your api response?)
{
'workitem_id': 1,
'workitem_header': 'header1',
'workitem_desc': 'description2',
'workitem_duration': 'duration2'
},
{
'workitem_id': 2,
'workitem_header': 'header2',
'workitem_desc': 'description2',
'workitem_duration': 'duration2'
}
]
results = []
for dictionary in dictionaries:
results.append(dictionary)
print(results)
Related
I was making a program where first parameter is a list and second parameter is a list of dictionaries. I want to return a list of lists like this:
As an example, if this were a function call:
make_lists(['Example'],
[{'Example': 'Made-up', 'Extra Keys' : 'Possible'}]
)
the expected return value would be:
[ ['Made-up'] ]
As an second example, if this were a function call:
make_lists(['Hint', 'Num'],
[{'Hint': 'Length 2 Not Required', 'Num' : 8675309},
{'Num': 1, 'Hint' : 'Use 1st param order'}]
)
the expected return value would be:
[ ['Length 2 Not Required', 8675309],
['Use 1st param order', 1]
]
I have written a code for this but my code does not return a list of lists, it just returns a single list. Please can someone explain?
def make_lists(s,lod):
a = []
lol =[]
i = 0
for x in lod:
for y in x:
for k in s:
if(y==k):
lol.append(x.get(y))
i = i+1
return lol
Expected Output:
[ ['Length 2 Not Required', 8675309],['Use 1st param order', 1] ]
Output:
['Length 2 Not Required', 8675309, 1, 'Use 1st param order']
The whole point of dictionaries, is that you can access them by key:
def make_lists(keys, dicts):
result = []
for d in dicts:
vals = [d[k] for k in keys if k in d]
if len(vals) > 0:
result.append(vals)
return result
Let's have a look what happens here:
We still have the result array, which accumulates the answers, but now it's called result instead of lol
Next we iterate through every dictionary:
for d in dicts:
For each dictionary d, we create a list, which is a lookup in that dictionary for the keys in keys, if the key k is in the dictionary d:
vals = [d[k] for k in keys if k in d]
The specs don't detail this, but I assume if none of the keys are in the dictionary, you don't want it added to the array. For that, we have a check if vals have any results, and only then we add it to the results:
if len(vals) > 0:
result.append(vals)
Try this code - I've managed to modify your existing code slighty, and added explanation in the comments. Essentially, you just need to use a sub-list and add that to the master list lol, and then in each loop iteration over elements in lod, append to the sub-list instead of the outermost list.
def make_lists(s,lod):
a = []
lol =[]
i = 0
for x in lod:
## Added
# Here we want to create a new list, and add it as a sub-list
# within 'lol'
lols = []
lol.append(lols)
## Done
for y in x:
for k in s:
if(y==k):
# Changed 'lol' to 'lols' here
lols.append(x.get(y))
i = i+1
return lol
print(make_lists(['Example'], [{'Example': 'Made-up', 'Extra Keys' : 'Possible'}]))
print(make_lists(['Hint', 'Num'], [{'Hint': 'Length 2 Not Required', 'Num' : 8675309}, {'Num': 1, 'Hint' : 'Use 1st param order'}]))
Prints:
[['Made-up']]
[['Length 2 Not Required', 8675309], [1, 'Use 1st param order']]
A simpler solution
For a cleaner (and potentially more efficient approach), I'd suggest using builtins like map and using a list comprehension to tackle this problem:
def make_lists(s, lod):
return [[*map(dict_obj.get, s)] for dict_obj in lod]
But note, that this approach includes elements as None in cases where the desired keys in s are not present in the dictionary objects within the list lod.
To work around that, you can pass the result of map to the filter builtin function so that None values (which represent missing keys in dictionaries) are then stripped out in the result:
def make_lists(s, lod):
return [[*filter(None, map(dict_obj.get, s))] for dict_obj in lod]
print(make_lists(['Example'], [{'Extra Keys' : 'Possible'}]))
print(make_lists(['Hint', 'Num'], [{'Num' : 8675309}, {'Num': 1, 'Hint' : 'Use 1st param order'}]))
Output:
[[]]
[[8675309], ['Use 1st param order', 1]]
Input:
list1 = [
{
"dict_a":"dict_a_values"
},
{
"dict_b":"dict_b_values"
},
{
"dict_c":"dict_c_values"
},
{
"dict_d":"dict_d_values"
}
]
Assuming n=2, every two elements have to be combined together.
Output:
list1 = [
{
"dict_a":"dict_a_values",
"dict_c":"dict_c_values"
},
{
"dict_b":"dict_b_values",
"dict_d":"dict_d_values"
}
]
Ideally, it'd be nicer if the output could look like something as follows with an extra layer of nesting:
[
{"dict_combined_ac": {
"dict_a":"dict_a_values",
"dict_c":"dict_c_values"
}},
{"dict_combined_bd": {
"dict_b":"dict_b_values",
"dict_d":"dict_d_values"
}}
]
But since this is really difficult to implement, I'd be more than satisfied with an output looking something similar to the first example. Thanks in advance!
What I've tried so far:
[ ''.join(x) for x in zip(list1[0::2], list1[1::2]) ]
However, I know this doesn't work because I'm working with dict elements and not str elements and when wrapping the lists with str(), every two letters is being combined instead. I'm also unsure of how I can adjust this to be for every n elements instead of just 2.
Given the original list, as in the question, the following should generate the required output:
result_list = list()
n = 2 # number of elements you want in each partition
seen_idx = set()
for i in range(len(list1)): # iterate over all indices
if i not in seen_idx:
curr_idx_list = list() # current partition
for j in range(i, len(list1), n): # generate indices for a combination partition
seen_idx.add(j) # keep record of seen indices
curr_idx_list.append(j) # store indices for current partition
# At this point we have indices of a partition, now combine
temp_dict = dict() # temporary dictionary where we store combined values
for j in curr_idx_list: # iterate over indices of current partition
temp_dict.update(list1[j])
result_list.append(temp_dict) # add to result list
print(result_list, '\n')
# Bonus: change result list into list of nested dictionaries
new_res_list = list()
for elem in result_list: # for each (combined) dictionary in the list, we make new keys
key_names = list(elem.keys())
key_names = [e.split('_')[1] for e in key_names]
new_key = 'dict_combined_' + ''.join(key_names)
temp_dict = {new_key: elem}
new_res_list.append(temp_dict)
print(new_res_list, '\n')
The output is as follows:
[{'dict_a': 'dict_a_values', 'dict_c': 'dict_c_values'}, {'dict_b': 'dict_b_values', 'dict_d': 'dict_d_values'}]
[{'dict_combined_ac': {'dict_a': 'dict_a_values', 'dict_c': 'dict_c_values'}}, {'dict_combined_bd': {'dict_b': 'dict_b_values', 'dict_d': 'dict_d_values'}}]
I have the following dictionary:
mydict = {'mindestens': 2,
'Situation': 3,
'österreichische': 2,
'habe.': 1,
'Über': 1,
}
How can I get a list / text out of it, that the strings in my dictionary are repeated as the number is mapped in the dictionary to it:
mylist = ['mindestens', 'mindestens', 'Situation', 'Situation', 'Situation',.., 'Über']
mytext = 'mindestens mindestens Situation Situation Situation ... Über'
You might just use loops:
mylist = []
for word,times in mydict.items():
for i in range(times):
mylist.append(word)
itertools library has convenient features for such cases:
from itertools import chain, repeat
mydict = {'mindestens': 2, 'Situation': 3, 'österreichische': 2,
'habe.': 1, 'Über': 1,
}
res = list(chain.from_iterable(repeat(k, v) for k, v in mydict.items()))
print(res)
The output:
['mindestens', 'mindestens', 'Situation', 'Situation', 'Situation', 'österreichische', 'österreichische', 'habe.', 'Über']
For text version - joining a list items is trivial: ' '.join(<iterable>)
Please check the below code and my output. I have run my code i got the below output but i want Expected Result.
list_data = ['ABCD:SATARA', 'XYZ:MUMBAI', 'PQR:43566', 'LMN:455667', 'XYZ:PUNE']
Expected Result is :-
{
"ABCD": "SATARA",
"XYZ": ["MUMBAI", "PUNE"]
"PQR": "43566",
"LMN": "455667"
}
My Code :-
list_data = ['ABCD:SATARA', 'XYZ:MUMBAI', 'PQR:43566', 'LMN:455667', 'XYZ:PUNE']
for each_split_data in list_data:
split_by_colon = each_split_data.split(":")
if split_by_colon[0] is not '':
if split_by_colon[0] in splittded_data_dict:
# append the new number to the existing array at this slot
splittded_data_dict[split_by_colon[0]].append(split_by_colon[1])
else:
# create a new array in this slot
splittded_data_dict[split_by_colon[0]] = [split_by_colon[1]]
print(json.dumps(splittded_data_dict, indent=2), "\n")
My OUTPUT :-
{
"ABCD": [
"SATARA"
],
"REF": [
"MUMBAI.",
"PUNE"
],
"PQR": [
"43566"
],
"LMN": [
"455667"
]
}
How can i solve the above problem?
The best thing to do in my opinion would be to use a defaultdict from the collections module. Have a look:
from collections import defaultdict
list_data = ['ABCD:SATARA', 'XYZ:MUMBAI', 'PQR:43566', 'LMN:455667', 'XYZ:PUNE']
res = defaultdict(list)
for item in list_data:
key, value = item.split(':')
res[key].append(value)
which results in:
print(res)
# defaultdict(<class 'list'>, {'ABCD': ['SATARA'], 'XYZ': ['MUMBAI', 'PUNE'], 'PQR': ['43566'], 'LMN': ['455667']})
or cast it to dict for a more familiar output:
res = dict(res)
print(res)
# {'ABCD': ['SATARA'], 'XYZ': ['MUMBAI', 'PUNE'], 'PQR': ['43566'], 'LMN': ['455667']}
From what I understand by the description of your problem statement, you want splittded_data_dict to be a dictionary where each value is a list
For this purpose try using defaultdict(). Please see the example below.
from collections import defaultdict
splittded_data_dict = defaultdict(list)
splittded_data_dict['existing key'].append('New value')
print(splittded_data_dict)
You can use the isinstance function to check if a key has been transformed into a list:
d = {}
for i in list_data:
k, v = i.split(':', 1)
if k in d:
if not isinstance(d[k], list):
d[k] = [d[k]]
d[k].append(v)
else:
d[k] = v
d becomes:
{'ABCD': 'SATARA', 'XYZ': ['MUMBAI', 'PUNE'], 'PQR': '43566', 'LMN': '455667'}
Let's append all possible key values from the string items in the list_data. Get the list of unique items. Now loop through the list_data and check if the first item of the ":" split string matched with the list a and if matches append to a temporary list and at last assign that temporary list as the value to the key of the item in the list a.
Here is oneliner using dict comprehension and list comprehension simultaneously :
c = {i : [j.split(":")[1] for j in list_data if j.split(":")[0] == i ][0] if len([j.split(":")[1] for j in list_data if j.split(":")[0] == i ])==1 else [j.split(":")[1] for j in list_data if j.split(":")[0] == i ] for i in list(set([i.split(":")[0] for i in list_data]))}
Output should be :
# c = {'LMN': '455667', 'ABCD': 'SATARA', 'PQR': '43566', 'XYZ': ['MUMBAI', 'PUNE']}
Here is the long and detailed version of the code :
list_data = ['ABCD:SATARA', 'XYZ:MUMBAI', 'PQR:43566', 'LMN:455667', 'XYZ:PUNE']
a = []
for i in list_data:
a.append(i.split(":")[0])
a = list(set(a))
b = {}
for i in a:
temp = []
for j in list_data:
if j.split(":")[0] == i:
temp.append(j.split(":")[1])
if len(temp) > 1:
b[i] = temp
else:
b[i] = temp[0]
I'm trying to get the matching IDs and store the data into one list. I have a list of dictionaries:
list = [
{'id':'123','name':'Jason','location': 'McHale'},
{'id':'432','name':'Tom','location': 'Sydney'},
{'id':'123','name':'Jason','location':'Tompson Hall'}
]
Expected output would be something like
# {'id':'123','name':'Jason','location': ['McHale', 'Tompson Hall']},
# {'id':'432','name':'Tom','location': 'Sydney'},
How can I get matching data based on dict ID value? I've tried:
for item in mylist:
list2 = []
row = any(list['id'] == list.id for id in list)
list2.append(row)
This doesn't work (it throws: TypeError: tuple indices must be integers or slices, not str). How can I get all items with the same ID and store into one dict?
First, you're iterating through the list of dictionaries in your for loop, but never referencing the dictionaries, which you're storing in item. I think when you wrote list[id] you mean item[id].
Second, any() returns a boolean (true or false), which isn't what you want. Instead, maybe try row = [dic for dic in list if dic['id'] == item['id']]
Third, if you define list2 within your for loop, it will go away every iteration. Move list2 = [] before the for loop.
That should give you a good start. Remember that row is just a list of all dictionaries that have the same id.
I would use kdopen's approach along with a merging method after converting the dictionary entries I expect to become lists into lists. Of course if you want to avoid redundancy then make them sets.
mylist = [
{'id':'123','name':['Jason'],'location': ['McHale']},
{'id':'432','name':['Tom'],'location': ['Sydney']},
{'id':'123','name':['Jason'],'location':['Tompson Hall']}
]
def merge(mylist,ID):
matches = [d for d in mylist if d['id']== ID]
shell = {'id':ID,'name':[],'location':[]}
for m in matches:
shell['name']+=m['name']
shell['location']+=m['location']
mylist.remove(m)
mylist.append(shell)
return mylist
updated_list = merge(mylist,'123')
Given this input
mylist = [
{'id':'123','name':'Jason','location': 'McHale'},
{'id':'432','name':'Tom','location': 'Sydney'},
{'id':'123','name':'Jason','location':'Tompson Hall'}
]
You can just extract it with a comprehension
matched = [d for d in mylist if d['id'] == '123']
Then you want to merge the locations. Assuming matched is not empty
final = matched[0]
final['location'] = [d['location'] for d in matched]
Here it is in the interpreter
In [1]: mylist = [
...: {'id':'123','name':'Jason','location': 'McHale'},
...: {'id':'432','name':'Tom','location': 'Sydney'},
...: {'id':'123','name':'Jason','location':'Tompson Hall'}
...: ]
In [2]: matched = [d for d in mylist if d['id'] == '123']
In [3]: final=matched[0]
In [4]: final['location'] = [d['location'] for d in matched]
In [5]: final
Out[5]: {'id': '123', 'location': ['McHale', 'Tompson Hall'], 'name': 'Jason'}
Obviously, you'd want to replace '123' with a variable holding the desired id value.
Wrapping it all up in a function:
def merge_all(df):
ids = {d['id'] for d in df}
result = []
for id in ids:
matches = [d for d in df if d['id'] == id]
combined = matches[0]
combined['location'] = [d['location'] for d in matches]
result.append(combined)
return result
Also, please don't use list as a variable name. It shadows the builtin list class.