I currently have a dict in the form:
data = {"var1":"600103", "var2":[{"a":"1","b":"2"}]}
I would like the output to be:
op = {"var1":"600103","var2[0]":{"a":"1","b":"2"}}
I am currently using loops to manually loop through. I'd like to know if there's a more pythonic way of doing this.
If this isn't what you're already doing, you can eliminate the need for a nested loop by using a dict comprehension for the values which are lists.
data = {"var1":"600103", "var2":[{"a":"1","b":"2"}, {"a":"22","b":"555"}]}
op = {}
for k in data:
if not isinstance(data[k], list):
op[k] = data[k]
else:
op.update({k + '[{}]'.format(i) : data[k][i] for i in range(len(data[k])) })
And, your output will look like this:
{'var1': '600103', 'var2[1]': {'a': '22', 'b': '555'}, 'var2[0]': {'a': '1', 'b': '2'}}
I do not know if it is very pythonic or not but I know for sure that it is difficult to read :S
Sorry, just playing... ;)
data = {"var1":"600103", "var2":[{"a":"1","b":"2"},{"a":"3","b":"4"},{"a":"5","b":"6"},{"a":"7","b":"8"}], "var3":"600103"}
reduce(
lambda a, b: dict(a.items() + b.items()),
[
dict(map(lambda (idx, i): ('{0}[{1}]'.format(key, idx), i), enumerate(value))) if type(value) is list else {key: value}
for key, value
in data.items()
]
)
output:
{'var1': '600103',
'var2[0]': {'a': '1', 'b': '2'},
'var2[1]': {'a': '3', 'b': '4'},
'var2[2]': {'a': '5', 'b': '6'},
'var2[3]': {'a': '7', 'b': '8'},
'var3': '600103'}
Related
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.
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'}
Does any one knows how to get the index of the values from dictionary 2 on dictionary 1.. like this:
Dictionary_1= {A: [Tom, Jane, Joe]; B: [Joana, Clare, Tom]; C: [Clare, Jane, Joe]}
Dictionary_2 = {A: Tom; B: Clare; C: Jane}
RESULT = {A: 1; B: 2; C: 2}
EDIT:
Sorry guys.. first of all I got confused and forgot that I needed it starting with "0" instead of "1".
I was having a problem, but it was because my list inside of dictionary 1 was in unicode format instead of list.
Also.. in the example I used here, I noticed later that the keys existed in both dictionaries, but in the code Im writting it wasnt the same thing. I didnt post the original here because it was bigger, so I tried to resume the most I could. Sorry for that too.
So I got it working with this code:
RESULT = {}
for x, y in Dictionary_1.items():
for a, b in Dictionary_2 .items():
if x == a:
z = Dictionary_1[x]
r = eval(z)
if '{0}'.format(b) in r:
RESULT [a] = r.index('{0}'.format(b))
I know that its looks messy but im still learning.
I really appreciate your help guys!
You can try using dict comprehension.
dict1={'A':['Tom','Jane','Joe'],'B':['Joana','Clare','Tom'],'C':['Clare','Jane','Joe']}
dict2={'A':'Tom','B':'Clare','C':'Jane'}
result={k:dict1[k].index(v)+1 for k,v in dict2.values()}
# {'A': 1, 'B': 2, 'C': 2}
#Or
# {k:dict1.get(k).index(v)+1 for k,v in dict2.items()}
Assuming you want 0-based indices, you can use list.index() with a dict comprehension:
d1 = {'A': ['Tom', 'Jane', 'Joe'], 'B': ['Joana', 'Clare', 'Tom'], 'C': ['Clare', 'Jane', 'Joe']}
d2 = {'A': 'Tom', 'B': 'Clare', 'C': 'Jane'}
result = {k: d1[k].index(v) for k, v in d2.items()}
print(result)
# {'A': 0, 'B': 1, 'C': 1}
If you want to have indices starting at 1, then you can do d1[k].index(v) + 1.
An easy to understand solution for you
d1 = {'A': ['Tom', 'Jane', 'Joe'], 'B': ['Joana', 'Clare', 'Tom'], 'C': ['Clare', 'Jane', 'Joe']}
d2 = {'A': 'Tom', 'B': 'Clare', 'C': 'Jane'}
output = {}
for k,v in d2.items():
output[k] = d1[k].index(v)+1
print(output)
This is certainly not the best approach but this is what I did quickly:
dict1 = {0: ['Tom', 'Jane', 'Joe'], 1: ['Joana', 'Clare', 'Tom'], 2: ['Clare', 'Jane', 'Joe']}
dict2 ={0: 'Tom', 1: 'Clare', 2: 'Jane'}
result = {}
val_list = list(dict1.values())
for i in range(0,len(dict1)):
result.update({i : val_list[i].index(dict2[i])})
print(result)
I wrote something like this to convert comma separated list to a dict.
def list_to_dict( rlist ) :
rdict = {}
i = len (rlist)
while i:
i = i - 1
try :
rdict[rlist[i].split(":")[0].strip()] = rlist[i].split(":")[1].strip()
except :
print rlist[i] + ' Not a key value pair'
continue
return rdict
Isn't there a way to
for i, row = enumerate rlist
rdict = tuple ( row )
or something?
You can do:
>>> li=['a:1', 'b:2', 'c:3']
>>> dict(e.split(':') for e in li)
{'a': '1', 'c': '3', 'b': '2'}
If the list of strings require stripping, you can do:
>>> li=["a:1\n", "b:2\n", "c:3\n"]
>>> dict(t.split(":") for t in map(str.strip, li))
{'a': '1', 'b': '2', 'c': '3'}
Or, also:
>>> dict(t.split(":") for t in (s.strip() for s in li))
{'a': '1', 'b': '2', 'c': '3'}
If I understand your requirements correctly, then you can use the following one-liner.
def list_to_dict(rlist):
return dict(map(lambda s : s.split(':'), rlist))
Example:
>>> list_to_dict(['alpha:1', 'beta:2', 'gamma:3'])
{'alpha': '1', 'beta': '2', 'gamma': '3'}
You might want to strip() the keys and values after splitting in order to trim white-space.
return dict(map(lambda s : map(str.strip, s.split(':')), rlist))
You mention both colons and commas so perhaps you have a string with key/values pairs separated by commas, and with the key and value in turn separated by colons, so:
def list_to_dict(rlist):
return {k.strip():v.strip() for k,v in (pair.split(':') for pair in rlist.split(','))}
>>> list_to_dict('a:1,b:10,c:20')
{'a': '1', 'c': '20', 'b': '10'}
>>> list_to_dict('a:1, b:10, c:20')
{'a': '1', 'c': '20', 'b': '10'}
>>> list_to_dict('a : 1 , b: 10, c:20')
{'a': '1', 'c': '20', 'b': '10'}
This uses a dictionary comprehension iterating over a generator expression to create a dictionary containing the key/value pairs extracted from the string. strip() is called on the keys and values so that whitespace will be handled.
for a list of dictionaries
sample_dict = [
{'a': 'woot', 'b': 'nope', 'c': 'duh', 'd': 'rough', 'e': '1'},
{'a': 'coot', 'b': 'nope', 'c': 'ruh', 'd': 'rough', 'e': '2'},
{'a': 'doot', 'b': 'nope', 'c': 'suh', 'd': 'rough', 'e': '3'},
{'a': 'soot', 'b': 'nope', 'c': 'fuh', 'd': 'rough', 'e': '4'},
{'a': 'toot', 'b': 'nope', 'c': 'cuh', 'd': 'rough', 'e': '1'}
]
How do I make a separate dictionary that contains all the key,value pair that match to a certain key. With list comprehension I created a list of all the key,value pairs like this:
container = [[key,val] for s in sample_dict for key,val in s.iteritems() if key == 'a']
Now the container gave me
[['a', 'woot'], ['a', 'coot'], ['a', 'doot'], ['a', 'soot'], ['a', 'toot']]
Which is all fine... but if I want to do the same with dictionaries, I get only a singe key,value pair. Why does this happen ?
container = {key : val for s in sample_dict for key,val in s.iteritems() if key == 'a'}
The container gives only a single element
{'a': 'toot'}
I want the something like
{'a': ['woot','coot','doot','soot','toot']}
How do I do this with minimal change to the code above ?
You are generating multiple key-value pairs with the same key, and a dictionary will only ever store unique keys.
If you wanted just one key, you'd use a dictionary with a list comprehension:
container = {'a': [s['a'] for s in sample_dict if 'a' in s]}
Note that there is no need to iterate over the nested dictionaries in sample_dict if all you wanted was a specific key; in the above I simply test if the key exists ('a' in s) and extract the value for that key with s['a']. This is much faster than looping over all the keys.
Another option:
filter = lambda arr, x: { x: [ e.get(x) for e in arr] }
So, from here, you can construct the dict based on the original array and the key
filter(sample_dict, 'a')
# {'a': ['woot', 'coot', 'doot', 'soot', 'toot']}