I have a list of dict that I am struggling to change to list of dicts:
x = [
{ # begin first and only dict in list
'11': [{'bb': '224', 'cc': '14'}, {'bb': '254', 'cc': '16'}]
, '22': [{'bb': '824', 'cc': '19'}]
}
]
Which currently has a length of 1. i.e.:
print(len(x)) # 1
I intend to change it to list of dicts. i.e.:
desired = [
{ # begin first dict in list
'11': [{'bb': '224', 'cc': '14'}, {'bb': '254', 'cc': '16'}]
}
, { # begin second dict in list
'22': [{'bb': '824', 'cc': '19'}]
}
]
print(len(desired)) # 2
What I tried:
dd = {}
for elem in x:
for k,v in elem.items():
dd[k] = v
print([dd])
print(len(dd)) # 2
Is there a better way or perhaps more efficient way?
Like others mentioned, there is nothing "wrong" with what you've tried. However, you might be interested in trying a list comprehension:
x_desired = [{k: v} for i in x for k, v in i.items()]
Like your attempted approach, this is effectively 2 for loops, the second nested within the first. In general, list comprehensions are considered fast and Pythonic.
Do you want the result to be 2 as you"ve got two keys (11 & 22) ?
then try this:
print(len(x[0]))
Related
I develop with python and i have a multiple dictionnary like:
Dict1: {‘hi’:’340’, ‘hello’:’570’, ’me’:´800’}
Dict1: {‘hi’:’200’, ‘hello’:’100’, ’me’:´389’}
And i would like to add them together into a dict like:
Dict_new= { {‘hi’:’340’,‘hello’:’570’, ’me’:´800’}, {‘hi’:’200’, ‘hello’:’100’, ’me’:´389’}}
Finally i would likt to have this output:
{‘elements’:{{‘hi’:’340’,‘hello’:’570’,
’me’:´800’},
{‘hi’:’200’, ‘hello’:’100’,
’me’:´389’}}}
So what is the best mannee to do this ?
Instead of using a set, please consider using a list which will store your dictionaries.
newDict = {}
newDict['element'] = [dict1,dict2]
output
{'elements': [{'hi': '340', 'hello': '570', 'me': '800'}, {'hi': '200', 'hello': '100', 'me': '389'}]}
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.
Is it possible to reuse a subexpression that might be large, or expensive to compute, or non-idempotent like a generator, in a comprehension?
Say there is a list of strings to be to converted to a dict:
items = ['ab: 1', 'cd: 2', 'ef:3'] ===> {'ab': '1', 'cd': '2', 'ef': '3'}
A loop computes the "expensive" split expression once:
d = {}
for item in items:
k, v = item.split(':', maxsplit=1)
d.update({k.strip(): v.strip()})
A comprehension repeats the computation for each output element:
d = {x.split(':', maxsplit=1)[0].strip(): x.split(':', maxsplit=1)[1].strip() for x in items}
But the desired solution is a comprehension that computes the expression once and then reuses it:
d = {k.strip(): v.strip() for x in items for k, v in x.split(':', maxsplit=1)} # Wrong - need an assignment
Can it be done?
If you don't need a dictionary comprehension, the dict object already takes in tuples:
dict(map(str.strip, x.split(':')) for x in items)
# {'ab': '1', 'cd': '2', 'ef': '3'}
And this would be the dict comprehension if you want:
{k: v for k, v in [map(str.strip, x.split(':')) for x in items]}
# {'ab': '1', 'cd': '2', 'ef': '3'}
a = ['ab: 1', 'cd: 2', 'ef:3']
Using generator expression with map and a dictionary comprehension.
In [46]: b = (map(str.strip,thing.split(':')) for thing in a)
In [47]: d = {k:v for (k,v) in b}
In [48]: d
Out[48]: {'ab': '1', 'cd': '2', 'ef': '3'}
Each item in a is split once and the items in the resultant list are stripped once. Execution of those functions is delayed till the dictionary comprehension is executed.
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'}
This question already has answers here:
How to sort two lists (which reference each other) in the exact same way
(14 answers)
Closed 9 years ago.
How would you sort lista according to order of items in sorter_list:
lista = [["John", "B3"],["Robert", "P3"], ["Thomas", "S2"]]
sorter_list = ["P3", "S2", "B3"]
and result will be:
sorted_lista = [ ["Robert", "P3"], ["Thomas", "S2"], ["John", "B3"]]
Regards
Assuming there will always be an entry in sorter_list that matches the second element of each list in lista:
sorted_lista = sorted(lista, key=lambda lst: sorter_list.index(lst[1]))
Although #F.J has a perfect solution, my question is, why aren't you using a dictionary for storing this kind of data in the first place?
With dictionary:
d = {'B3': 'John', 'P3': 'Robert', 'S2': 'Thomas'}
sorter = ["P3", "S2", "B3"]
print([(d[key], key) for key in sorter])
Output:
[('Robert', 'P3'), ('Thomas', 'S2'), ('John', 'B3')]
Plus: You should also check the collections module's OrderedDict.
UPDATE:
Of course, you can store the values as lists, so one can hold multiple values:
With dictionary:
d = {'B3': [('John', 123)], 'P3': [('Robert', 465), ('Andres', 468)], 'S2': [('Thomas', 19)]}
sorter = ('P3', 'B3', 'S2')
print([(d[key], key) for key in sorter])
Output:
[([('Robert', 465), ('Andres', 468)], 'P3'), ([('John', 123)], 'B3'), ([('Thomas', 19)], 'S2')]
In this case, you can also use a dictionary inside a dictionary:
d = {'B3': {'John': 123}, 'P3': {'Robert': 465, 'Andres': 468}, 'S2': {'Thomas': 19}}
And the lookup will be much easier later on.
You can do this in O(N) by building a dictionary, where your keys are the B3, S2 etc.
lookup_dict = dict( (item[1],item) for item in lista)
sorted_lista = [ lookup_dict[key] for key in sorter_list ]
This takes advantage of the fact that your sorter_list is already sorted.
To sort efficient I think it's better to create a dictionary from sorter_list
sorter_dict = {x:i for i, x in enumerate(sorter_list)}
sorted_lista = sorted(lista, key=lambda lst: sorter_dict[lst[1]])
I'm newbie in python so it may not be the most optimized solution
sorted_lista=[]
for i in sorter_list:
for j in lista:
if i==j[1]:
sorted_lista.append([j[0],j[1]])
print sorted_lista
Output :
[['Robert', 'P3'], ['Thomas', 'S2'], ['John', 'B3']]