Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Could somebody help me to transform this:
a = [{'one': 4, 'name': 'value1', 'two': 25}, {'one': 2, 'name': 'value1', 'two': 18}, {'one': 1, 'name': 'value1', 'two': 15}, {'one': 2, 'name': 'value2', 'two': 12}, {'one': 1, 'name': 'value2', 'two': 10}]
to something like this:
b = [{'value1': [(4, 25), (2, 18), (1, 15)]}, {'value2': [(2, 12), (1, 10)]}]
try this:
>>> di = {}
>>> for i in a:
... if di.get(i['name']):
... di[i['name']].append((i['one'], i['two']))
... else:
... di[i['name']] = []
... di[i['name']].append((i['one'], i['two']))
I reccomend to do like this:
#First create a small dictionary, wich is used to get the keys(name,two,one):
smalld = {'name': 'value1', 'two': 25, 'one': 4}
#Then create the big dict, the dict you are going to get the data
bigd = [{'one': 4, 'name': 'value1', 'two': 25},
{'one': 2, 'name': 'value1', 'two': 18},
{'one': 1, 'name': 'value1', 'two': 15},
{'one': 2, 'name': 'value2', 'two': 12},
{'one': 1, 'name': 'value2', 'two': 10}]
#Then create empty final dict where you
#will use the other dict to create this one
finald = {}
#and now the "magic" loop. k get keys value and run over the big dict to get data.
for k in smalld.iterkeys():
finald[k] = tuple(finald[k] for finald in bigd) #Edited, this line had a mistake
a = [{'one': 4, 'name': 'value1', 'two': 25},
{'one': 2, 'name': 'value1', 'two': 18},
{'one': 1, 'name': 'value1', 'two': 15},
{'one': 2, 'name': 'value2', 'two': 12},
{'one': 1, 'name': 'value2', 'two': 10}]
_d = {ele['name']:[] for ele in a}
for _dict in a:
_temp = {_dict['name']:(_dict['one'], _dict['two']) for ele in _dict}
_d[_temp.keys()[0]].append(_temp[_temp.keys()[0]])
print _d
Output:
{'value2': [(2, 12), (1, 10)], 'value1': [(4, 25), (2, 18), (1, 15)]}
Related
I have a slightly weird input of data that is in this format:
data = { 'sensor1': {'units': 'x', 'values': [{'time': 17:00, 'value': 10},
{'time': 17:10, 'value': 12},
{'time': 17:20, 'value' :7}, ...]}
'sensor2': {'units': 'x', 'values': [{'time': 17:00, 'value': 9},
{'time': 17:20, 'value': 11}, ...]}
}
And I want to collect the output to look like:
{'17:00': [10,9], '17:10': [12,], '17:20': [7,11], ... }
So the keys are the unique timestamps (ordered) and the values are a list of the values of each sensor, in order they come in the original dictionary. If there is no value for the timestamp in one sensor, it is just left as an empty element ''. I know I might need to use defaultdict but I've not had any success.
e.g.
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
d[k].append(v)
sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
d = defaultdict(default_factory=list)
values_list = data.values()
for item in values_list:
for k, v in item['values']:
d[k].append(v)
result = sorted(d.items())
Encounters key error as each item in values_list is not a tuple but a dict.
You can also use dict in this way:
data = {'sensor1': {'units': 'x', 'values': [{'time': '17:00', 'value': 10},
{'time': '17:10', 'value': 12},
{'time': '17:20', 'value': 7},
]},
'sensor2': {'units': 'x', 'values': [{'time': '17:00', 'value': 9},
{'time': '17:20', 'value': 11},
]}
}
d = {}
for item in data.values():
for pair in item['values']:
if pair["time"] in d:
d[pair["time"]].append(pair["value"])
else:
d[pair["time"]] = [pair["value"]]
result = sorted(d.items())
print(result)
Output:
[('17:00', [10, 9]), ('17:10', [12]), ('17:20', [7, 11])]
Using defaultdict defaultdict example with list in Python documentation :
from collections import defaultdict
data = {'sensor1': {'units': 'x', 'values': [{'time': '17:00', 'value': 10},
{'time': '17:10', 'value': 12},
{'time': '17:20', 'value': 7},
]},
'sensor2': {'units': 'x', 'values': [{'time': '17:00', 'value': 9},
{'time': '17:20', 'value': 11},
]}
}
d = defaultdict(list)
for item in data.values():
for pair in item['values']:
d[pair["time"]].append(pair["value"])
result = sorted(d.items())
print(result)
Output:
[('17:00', [10, 9]), ('17:10', [12]), ('17:20', [7, 11])]
Was wondering if anyone could help me with counting duplicate dictionarys. I have this list:
a = [{'key1':1, 'key2':2, 'key3':3, 'count': 0},
{'key1':1, 'key2':2, 'key3':4, 'count': 0},
{'key1':3, 'key2':2, 'key3':4, 'count': 0},
{'key1':1, 'key2':2, 'key3':3, 'count': 0}]
i`m lookig to count all duplicates and once it is match remove copy and append to that dictionry ['count'] += 1. so final result might look like
a = [{'key1':1, 'key2':2, 'key3':3, 'count': 2},
{'key1':1, 'key2':2, 'key3':4, 'count': 0},
{'key1':3, 'key2':2, 'key3':4, 'count': 0}]
i did tryed simple aprouch such as which didnt worked:
a = [{'key1':1, 'key2':2, 'key3':3, 'count': 0},
{'key1':1, 'key2':2, 'key3':4, 'count': 0},
{'key1':3, 'key2':2, 'key3':4, 'count': 0},
{'key1':1, 'key2':2, 'key3':3, 'count': 0}]
for i in range(len(a)):
for n in range(len(a)):
if a[i]['key1'] == a[n]['key1'] and a[i]['key2'] == a[n]['key2'] and a[i]['key3'] == a[n]['key3']:
a[i]['count'] += 1
del a[n]
was thinking aswell there should be some simpler aprouch. thanks
You can leverage Counter method in the collections module.
import collections
count = collections.Counter([tuple(d.items()) for d in a])
[dict(k) | {c:v} for (*k, (c,_)), v in count.items()]
this looks like:
[{'key1': 1, 'key2': 2, 'key3': 3, 'count': 2},
{'key1': 1, 'key2': 2, 'key3': 4, 'count': 1},
{'key1': 3, 'key2': 2, 'key3': 4, 'count': 1}]
I need to create a dictionary of list of dictionaries or if there is any other way of achieving the below requirement:
i have a set of keys let say
keys = [1,2,3,4,5] (dont consider this as list but i am just showing i have let say 5 keys)
for each key i will have a set of key value pair so something lime below:
d = {
1:{
{'one': 'test', 'two': 'new', 'three': 'dummy'}
{'one': 'testtest', 'two': 'newnew', 'three': 'dummyextra'}
{'one': 'newvalue', 'two': 'newvalue2', 'three': 'newvalue4'}
}
2:{
{'one': 'test1', 'two': 'new1', 'three': 'dummy1'}
{'one': 'testtest2', 'two': 'newnew2', 'three': 'dummyextra2'}
{'one': 'newvalue3', 'two': 'newvalue23', 'three': 'newvalue43'}
}
1:{
{'one': 'test', 'two': 'new', 'three': 'dummy'}
{'one': 'testtest', 'two': 'newnew', 'three': 'dummyextra'}
{'one': 'newvalue', 'two': 'newvalue2', 'three': 'newvalue4'}
}
}
All the inner and outer dictionaries will be forming through loops.
If because of unique key the above is not possible than what will be the alternate solution to get the data in above format (list of dictionaries or dictionary of lists or anything else?).
With above my main agenda is i will have a unique tag that will be the key of outer dictionary and using that tag i will be creating one HTML header,
under that header i will b populating the data i.e. multiple links and that internal data has to come from inner dictionary from the example.
So in this example i have an html page with header title 1 and under this header i will have 3 links that wil come from inner dictionary.
Than i will have header 2 and again 3 links under it and so on.
Kindly help me to achieve this.
Thanks,
You just have to represent lists with [] not {} and don't forget the commas (,) to separate the elements:
d = {
1:[
{'one': 'test', 'two': 'new', 'three': 'dummy'},
{'one': 'testtest', 'two': 'newnew', 'three': 'dummyextra'},
{'one': 'newvalue', 'two': 'newvalue2', 'three': 'newvalue4'}
],
2:[
{'one': 'test1', 'two': 'new1', 'three': 'dummy1'},
{'one': 'testtest2', 'two': 'newnew2', 'three': 'dummyextra2'},
{'one': 'newvalue3', 'two': 'newvalue23', 'three': 'newvalue43'}
],
3:[
{'one': 'test', 'two': 'new', 'three': 'dummy'},
{'one': 'testtest', 'two': 'newnew', 'three': 'dummyextra'},
{'one': 'newvalue', 'two': 'newvalue2', 'three': 'newvalue4'}
]
}
Try to guess something similar to your input (dlist) just to how how to build a dict using a list as a default value and appending data:
dlist = [[2, {'two': 'two1'}], [1, {'one': 'one1'}], [1, {'one': 'one2'}], [2, {'two': 'two2'}] ]
res = {}
for item in dlist:
res.setdefault(item[0], list()).append(item[1])
print(res)
#=> {1: [{'one': 'one1'}, {'one': 'one2'}], 2: [{'two': 'two1'}, {'two': 'two2'}]}
This question already has answers here:
Fast Algorithm to Quickly Find the Range a Number Belongs to in a Set of Ranges?
(5 answers)
Closed 4 years ago.
I have a list of dictionaries in the following way:
list1 = [{'some_id': 1, 'lower_range': 3, 'upper_range': 7},
{'some_id': 2, 'lower_range': 8, 'upper_range': 12},
{'some_id': 3, 'lower_range': 13, 'upper_range': 16}]
A second list contains some integers:
list2 = [{'value': 4, 'data': 'A'},
{'value': 8, 'data': 'B'},
{'value': 9, 'data': 'C'},
{'value': 15, 'data': 'D'}]
I now want to join 'some_id' and 'data' such that 'value' is between 'lower_range' and 'upper_range' in a new list. I.e., I want the output to be
list3 = [{'some_id': 1, 'data': 'A'},
{'some_id': 2, 'data': 'B'},
{'some_id': 2, 'data': 'C'},
{'some_id': 3, 'data': 'D'}]
One way to do this would be
list3 = []
for i in list1:
for j in list2:
if (j['value'] >= i['lower_range'] and
j['value'] <= i['upper_range']):
list3.append({'some_id': i['some_id'], 'data': j['data']})
However, this seems highly inefficient. Is there some faster way?
There is a special premise that the ranges do not overlap.
So we can find a candidate by searching for an element with the maximum lower_bound that satisfies the condition.
Binary search can reduce complexity from O(n*n) to O(n log n).
In python3, we can use bisect.
list1 = [{'some_id': 1, 'lower_range': 3, 'upper_range': 7},
{'some_id': 2, 'lower_range': 8, 'upper_range': 12},
{'some_id': 3, 'lower_range': 13, 'upper_range': 16}]
list2 = [{'value': 4, 'data': 'A'},
{'value': 8, 'data': 'B'},
{'value': 9, 'data': 'C'},
{'value': 15, 'data': 'D'}]
list3 = []
list1.sort(key = lambda r: r['lower_range'])
lower_ranges = [r['lower_range'] for r in list1]
from bisect import bisect_right
for record in list2:
position = bisect_right(lower_ranges, record['value']) - 1
if (position < 0): continue
candidate = list1[position]
if (record['value'] <= candidate['upper_range']):
list3.append({'some_id': candidate['some_id'], 'data': record['data']})
print(list3)
output (manual indented)
[{'some_id': 1, 'data': 'A'},
{'some_id': 2, 'data': 'B'},
{'some_id': 2, 'data': 'C'},
{'some_id': 3, 'data': 'D'}]
This is a bit verbose but should be more efficient (O(nlogn) < O(n^2)) due to sorting (you can also sort in-place with list.sort):
#!/usr/bin/env python
from operator import itemgetter
list1 = [{'some_id': 1, 'lower_range': 3, 'upper_range': 7},
{'some_id': 2, 'lower_range': 8, 'upper_range': 12},
{'some_id': 3, 'lower_range': 13, 'upper_range': 16}]
list2 = [{'value': 4, 'data': 'A'},
{'value': 8, 'data': 'B'},
{'value': 9, 'data': 'C'},
{'value': 15, 'data': 'D'}]
# sort before merging so we iterate less (O(nlogn))
list1 = sorted(list1, key=itemgetter('lower_range'))
list2 = sorted(list2, key=itemgetter('value'))
it1 = iter(list1)
it2 = iter(list2)
# merge lists that we know are sorted (simple merging algorithm - O(n))
try:
curr_range = next(it1)
curr_val = next(it2)
list3 = []
while True:
rng = range(curr_range['lower_range'], curr_range['upper_range'] + 1)
value = curr_val['value']
if value in rng:
# got a match, add it and check if there are more values
list3.append({'some_id': curr_range['some_id'],
'data': curr_val['data']})
curr_val = next(it2)
continue
if value < curr_range['lower_range']:
# no match, skip to next value
curr_val = next(it2)
continue
if value >= curr_range['upper_range']:
# range too low for value, try next one
curr_range = next(it1)
continue
except StopIteration:
pass
print(list3)
Gives:
[{'data': 'A', 'some_id': 1},
{'data': 'B', 'some_id': 2},
{'data': 'C', 'some_id': 2},
{'data': 'D', 'some_id': 3}]
You could create a dict that maps values to ids like {3: 1, 4: 1, 5: 1, ..., 8: 2, 9: 2, ...}, which would let you find each dict's id in constant O(1) time:
# create a dict that maps values to ids
value_to_id_dict = {}
for dic in list1:
id_ = dic['some_id']
for value in range(dic['lower_range'], dic['upper_range']+1):
value_to_id_dict[value] = id_
# look up each dict's id in the dict we just created
list3 = []
for dic in list2:
new_dic = {'data': dic['data'],
'some_id': value_to_id_dict[dic['value']]}
list3.append(new_dic)
# result:
# [{'data': 'A', 'some_id': 1},
# {'data': 'B', 'some_id': 2},
# {'data': 'C', 'some_id': 2},
# {'data': 'D', 'some_id': 3}]
I am tying to replace a small sql database with a dictionary. The only one problem I am facing is with query. Its just becoming so complicated. here is the example:
foo={'id_1': {'location': 'location_1', 'material': 'A'},
'id_2': {'location': 'location_1', 'material': 'A'},
'id_3': {'location': 'location_1', 'material': 'B'},
'id_4': {'location': 'location_2', 'material': 'B'},
'id_5': {'location': 'location_2', 'material': 'A'},
'id_6': {'location': 'location_1', 'material': 'C'},
'id_7': {'location': 'location_1', 'material': 'A'},
'id_8': {'location': 'location_2', 'material': 'B'}}
So, I wanted to to some query based on locations and the result should look like this:
{'location_1' : {'A': 3, 'B': 1, 'C': 1}, 'location_2': {'A':1,'B':2}}
Is there any way to do query on python dictionary? Or at least neat way of doing it ?
Thanks
You'd need to use a defaultdict() and Counter() object to achieve what you want:
results = defaultdict(Counter)
for entry in foo.values():
results[entry['location']][entry['material']] += 1
which produces:
defaultdict(<class 'collections.Counter'>, {
'location_2': Counter({'B': 2, 'A': 1}),
'location_1': Counter({'A': 3, 'C': 1, 'B': 1})
})
but using an actual database (such as the bundled sqlite3) would be far more efficient.
How about this:
d = {}
for k,v in foo.iteritems():
loc = v['location']
mat = v['material']
d.setdefault(loc, {})
d[loc].setdefault(mat, 0)
d[loc][mat] = d[loc].get(mat, 0) + 1
print d
Output:
{'location_2': {'A': 1, 'B': 2}, 'location_1': {'A': 3, 'C': 1, 'B': 1}}