Appending dictionary to list with different value same key - python

I have a list of dictionaries, that have same keys and some have different values for those keys. I am trying to append the dictionaries that have different values from the list to keep track of the different values and I would concatenate the values of other keys. For example, I am storing 'a' keys with same values and concatenating the 'b' values that have same 'a':'1'
input list: d = [{'a': '1', 'b': '3'}, {'a': '2', 'b': '4'}, {'a': '1', 'b':'5'}]
output list: p = [{'a':'1', 'b': '35'}, {'a': '2', 'b': '4'}]
So far, I tried the following code, but it doesnt recognize the different values
length = len(p)
j = 0
for i in d:
while j < length:
if p[j]['a'] is not i['a']:
p.append({'a', p[j]['a']})
else:
p[j]['b'] += i['b']
j += 1
j = 0
any tips would be appreciated

Use a dictionary that has the a values as its keys so you don't have to loop through the result list for a matching a.
temp_dict = {}
for item in d:
if item['a'] in temp_dict:
temp_dict[item['a']]['b'] += item['b']
else:
temp_dict[item['a']] = item.copy()
p = list(temp_dict.values())

Related

Extract subset of dictionaries inside a list of dictionaries until particular key is found

I have a list of dict
dict = [{'a':'1'},{'b':'2'},{'c':'3'},{'Stop':'appending'},{'d':'4'},{'e':'5'},{'f':'6'}]
dict1 = [{'a':'1'},{'b':'2'},{'c':'3'},{'d':'4'},{'Stop':'appending'},{'e':'5'},{'f':'6'}]
I want to extract all list elements until key 'Stop' is found and append it to new dictionary
Expected output:
new_dict = [{'a':'1'},{'b':'2'},{'c':'3'}]
new_dict1 = [{'a':'1'},{'b':'2'},{'c':'3'},{'d':'4'}]
Code:
temp_dict = []
for i in range(0,len(list)):
for key,value in list[i].items():
if key == 'Stop':
break
temp_dict.append(list[i])
It's already in standard library
import itertools
dict1 = [{'a':'1'},{'b':'2'},{'c':'3'},{'d':'4'},{'Stop':'appending'},{'e':'5'},{'f':'6'}]
res = list(itertools.takewhile(lambda x: "Stop" not in x, dict1))
print(res)
output:
[{'a': '1'}, {'b': '2'}, {'c': '3'}, {'d': '4'}]
You can use enumerate() to get the index of the element matching the key Stop and then used list slicing on top of that:
dic = [{'a':'1'},{'b':'2'},{'c':'3'},{'Stop':'appending'},{'d':'4'},{'e':'5'},{'f':'6'}]
index = next(index for index, elt in enumerate(dic) if elt.get('Stop'))
new_dic = dic[0:index] # [{'a': '1'}, {'b': '2'}, {'c': '3'}]
Also, don't use dict keyword for object names to avoid shadowing built-in primitives.
Update: If you want to just skip the element with key Stop and take all others then update the above slicing operation as:
new_dic = dic[0:index] + dic[index+1:] # [{'a': '1'}, {'b': '2'}, {'c': '3'}, {'d': '4'}, {'e': '5'}, {'f': '6'}]
First find the index of the elements that have 'Stop' like a key, and after that just slice the list to the first of those index.
Try:
inds = [i for i in range(len(dict1)) if 'Stop' in dict1[i].keys()]
new_dict1 = dict1[:inds[0]]
Also, I think you should choice better names for your lists, especially for the first, dict is a reserved word in python.

Sort a python dictionary based on input value?

I have a dictionary with four keys a,b,c,d with values 100,200,300,400
list1 = {'a':'100','b':'200','c':'300','d':'400'}
And a variable inputs.
inputs = 'c'
If inputs is c. The list1 dictionary has to be sorted based on it.
inputs = 'c'
list1 = {'c':'300','a':'100','b':'200','d':'400'}
inputs = 'b'
list1 = {'b':'200','a':'100','c':'300','d':'400'}
In Python3.7+ dict keys are stored in the insertion order
k ='c'
d={k:list1[k]}
for key in list1:
if key!=k:
d[key]=list1[key]
Output
{'c': '300', 'a': '100', 'b': '200', 'd': '400'}
Seems like you just want to rearrange your dict to have the chosen value at the front, then the remaining keys afterwards:
dict1 = {'a':'100','b':'200','c':'300','d':'400'}
key = 'c'
result = {key: dict1[key], **{k: v for k, v in dict1.items() if k != key}}
print(result)
# {'c': '300', 'a': '100', 'b': '200', 'd': '400'}
The ** simply merges the leftover filtered keys with key: dict1[key].
If you just want to change the position to the first one a given value if it exists, it could be done in the following way:
list1 = {'a':'100','b':'200','c':'300','d':'400'}
inputs = 'c'
output = {}
if inputs in list1.keys():
output[inputs] = list1.get(inputs)
for i in list1.keys():
output[i] = list1[i]
Output;
{'c': '300', 'a': '100', 'b': '200', 'd': '400'}
Here's a one-liner:
d = {'a':'100','b':'200','c':'300','d':'400'}
i = input()
d = {i:d[i],**{k:d[k] for k in d if k!=i}}
print(list1)
Input:
c
Output:
{'a': '100', 'b': '200', 'd': '400', 'c': '300'}

update a nested dictionary with values of a list

Need to iterate the list values in the nested dictionary
d = { 'a' :{'a': '3','b': '2 '},'b':{'c':'1'}}
temp = (20,31,111,455,55,6)
for i in d:
for j in d[i]:
for k in temp:
d[i][j]=k
print d
I expect the following:
d = { 'a' :{'a': '20','b': '31 '},'b':{'c':'111'}}
Try this:
d = { 'a' :{'a': '3','b': '2 '},'b':{'c':'1'}}
temp = (20,31,111,455,55,6)
count=0
for i in d:
for j in d[i]:
#update nested dictionary value
d[i][j]=temp[count]
#increment count variable
count+=1
print(d)
O/P:
{'a': {'a': 20, 'b': 31}, 'b': {'c': 111}}

How to add index to a list inside a dictionary

I have a dictionary here:
dict = {'A':['1','1','1','1','1'], 'B':['2','2'], 'C':['3','3','3','3']}
What is the necessary process to get the following result?
dict = {'A':['1_01','1_02','1_03','1_04','1_05'], 'B':['2_01','2_02'], 'C':['3_01','3_02','3_03','3_04']}
I have been learning python for quite a while now but dictionary is kind of new to me.
As others mentioned, refrain from using built-in keywords as variable names, such as dict. I kept it for simplicity on your part.
This is probably the most pythonic way of doing it (one line of code):
dict = {key:[x+"_0"+str(cnt+1) for cnt,x in enumerate(value)] for key,value in dict.items()}
You could also iterate through each dictionary item, and then each list item and manually change the list names as shown below:
for key,value in dict.items():
for cnt,x in enumerate(value):
dict[key][cnt] = x+"_0"+str(cnt+1)
Also, as some others have mentioned, if you want numbers greater than 10 to save as 1_10 rather than 1_010 you can you an if/else statement inside of the list comprehension...
dict = {key:[x+"_0"+str(cnt+1) if cnt+1 < 10 else x+"_"+str(cnt+1) for cnt,x in enumerate(value)] for key,value in dict.items()}
First iterate on keys.
Then loop on keys you are getting on key like for 'A' value is ['1','1','1','1','1'] then we can change the element at ['1','1','1','1','1']
enumerate() helps you iterate on index,value then index starts with zero as per your expected output add 1 to index. As you want the trailing 0 before each count we did '%02d'% (index+1)
Like this:
dict = {'A':['1','1','1','1','1'], 'B':['2','2'], 'C':['3','3','3','3']}
for i in dict.keys(): #iterate on keys
for index,val in enumerate(dict[i]): #took value as we have key in i
element='%02d'% (index+1) #add trailing 0 we converted 1 to int 01
dict[i][index]=val+"_"+ str(element) #assign new value with converting integer to string
print(dict)
Output:
{'A': ['1_01', '1_02', '1_03', '1_04', '1_05'], 'C': ['3_01', '3_02', '3_03', '3_04'], 'B': ['2_01', '2_02']}
Use enumerate to iterate over list keeping track of index:
d = {'A':['1','1','1','1','1'], 'B':['2','2'], 'C':['3','3','3','3']}
newd = {}
for k, v in d.items():
newd[k] = [f'{x}_0{i}' for i, x in enumerate(v, 1)]
print(newd)
Also a dictionary-comprehension:
d = {k: [f'{x}_0{i}' for i, x in enumerate(v, 1)] for k, v in d.items()}
Note: Don't name your dictionary as dict because it shadows the built-in.
d= {'A':['1','1','1','1','1'], 'B':['2','2'], 'C':['3','3','3','3']}
{x:[j + '_'+ '{:02}'.format(i+1) for i,j in enumerate(y)] for x,y in d.items()}
adict = {'A':['1','1','1','1','1'], 'B':['2','2'], 'C':['3','3','3','3'], 'D': '23454'}
newdict = {}
for i,v in adict.items():
if isinstance(v, list):
count = 0
for e in v:
count += 1
e += '_0' + str(count)
newdict[i] = newdict.get(i, [e]) + [e]
else:
newdict[i] = newdict.get(i, v)
print (newdict)
#{'A': ['1_01', '1_01', '1_02', '1_03', '1_04', '1_05'], 'B': ['2_01', '2_01', '2_02'], 'C': ['3_01', '3_01', '3_02', '3_03', '3_04'], 'D': '23454'}
This solution will check for whether your value in the dictionary is a list before assigning an index to it
You can use a dictcomp:
from itertools import starmap
d = {
'A': ['1', '1', '1', '1', '1'],
'B': ['2', '2'],
'C': ['3', '3', '3', '3']
}
f = lambda x, y: '%s_%02d' % (y, x)
print({k: list(starmap(f, enumerate(v, 1))) for k, v in d.items()})
# {'A': ['1_01', '1_02', '1_03', '1_04', '1_05'], 'B': ['2_01', '2_02'], 'C': ['3_01', '3_02', '3_03', '3_04']}

How to find the similarities for set and print the value

I hope to make a dictionary and a list into set then if a.keys() == b then I will print the a.values().
Example:
c = [{'1': '0'}, {'0': '5'},{'2': '0'}]
d = {1,2}
I hope to make these two into the set. Then find all the similarities and print the values without changing the sequence.
Example, I want to print this.
{'1': '0'}
{'2': '0'}
Is it possible to use set?
Below is my code:
a = set(c.keys()) & set(d)
print(a)
for x in a:
y,z = c[x]
Since your example set contains integers while the keys in your example dicts are strings, you should convert the integers in the set to strings first. After that you can simply loop through each dict in the list and if the keys of the dict intersects with the set, then print the dict since it's a match:
d = set(map(str, d))
for i in c:
if i.keys() & d:
print(i)
This outputs:
{'1': '0'}
{'2': '0'}
First of all, you specified your input values the wrong way. The dictionary c should be defined as a dictionary with keys and values and not as a list of dictionaries with one item each - as you did. The keys should be specified as integer and not as string. Otherwise you need to cast them from string to int later on. The second item d is specified the wrong way, too. This should be a list of integers and not a dictionary.
Here's the code that specifies the input values correctly and gives you the desired output:
c = {1: '0', 0: '5', 2: '0'}
d = [1,2]
distinct_keys = c.keys() & set(d)
# {1, 2}
distinct_values = {key: value for key, value in c.items() if key in distinct_keys}
# {1: '0', 2: '0'}
distinct_values
This gives {1: '0', 2: '0'} as output.

Categories