I am trying to limit the ordering of a dictionary but the ouput that I get are returned in a sorted order which is something I do not want.
test = {}
test['bbb'] = '0'
test['aaa'] = '1'
# Returns me {'aaa': '1', 'bbb': '0'} when I am expecting {'bbb': '0', 'aaa': '1'}
The above is a simple example, in which both aaa and bbb are queried from a list. And I had thought this may have resolves the ordering but it did not.
Dictionary is not preserving the order of added elements. You need to use collections.OrderedDict instead to have this feature available.
Related
I have a nested dictionary where i am trying to print the corresponding value of the nested key without requiring the outermost numeral key input.
e.g. if roomname in nested-nested dictionary, print room area.
and my dictionary is set up like below:
d = {0: {'RoomName': 'PSC', 'MinArea': '28', 'MinRoomDim': 'null', 'MinDoorWidth': '900', 'MinDoorHeight': '2100', 'NoofDoorLeaves': '1', 'DoorMaterial': 'Glass', 'ReferenceLocation': 'LTA ADC SECTION 3.1 CLAUSE 5.1', 'RoomSpecificInfo': 'Refer to PSC design guidelines'},
1: {'RoomName': 'SMR', 'MinArea': '8', 'MinRoomDim': 'null', 'MinDoorWidth': '900', 'MinDoorHeight': '2100', 'NoofDoorLeaves': '1', 'DoorMaterial': 'Glass', 'ReferenceLocation': 'LTA ADC SECTION 3.1 CLAUSE 5.2', 'RoomSpecificInfo': 'null'},
2: {'RoomName': 'FIRST AID RM', 'MinArea': '7.5', 'MinRoomDim': '3.0m x 2.5m', 'MinDoorWidth': '1000', 'MinDoorHeight': '2100', 'NoofDoorLeaves': '1', 'DoorMaterial': 'null', 'ReferenceLocation': 'LTA ADC SECTION 3.1 CLAUSE 5.3', 'RoomSpecificInfo': 'null'},...
So far all the solutions I managed to find are for typical dictionaries and the solution does not work for nested dictionaries like above. Any help would be appreciated.
You can print nested dictionaries like this:
for i,j in d.items():
for m,n in j.items():
print(m,n)
where m is the key and n is the value of the nested dictionary
Read the json file and then use multiple loads and get() inside to get the required value in the nested json for example to get in key '1' to get RoomName
json.loads(json.loads(x).get("1","{}")).get("RoomName"))
I have a form, which one of the fields is a multiselect, I am trying to retrieve all the values that where selected, but form some reason I only get the last item selected:
print(type(self.get_form().data))
# <class 'django.http.request.QueryDict'>
print(self.get_form().data)
# <QueryDict: {'csrfmiddlewaretoken': ['K0GeMv5u8pnT3fnS1lnXjgYakuu2mkXg61GKMVuJc2bBnDH1YMTPUHr6iY3rsZ0A'], 'contactID': ['20'], 'locationID': ['2'], 'items': ['1', '3']}>
In this point items is equal to: 'items': ['1', '3'], however when i try to get items:
print(self.get_form().data.get('items'))
that prints 3
What I am doing wrong?
QueryDict.get() returns the last value. It is how it works
If you need it as a normal python dictionary, then convert it using dict():
print(dict(self.get_form().data).get('items'))
With the following list of dict:
[ {'isn': '1', 'fid': '4', 'val': '1', 'ptm': '05/08/2019 14:22:39', 'sn': '111111' 'procesado': '0'},
{'isn': '1', 'fid': '4', 'val': '0', 'ptm': '05/08/2019 13:22:39', 'sn': '111111', 'procesado': '0'},
<...> ]
I would need to compare for each dict of the list if there are other element with:
equal fid
equal sn
distinct val (if val(elemX)=0 then val(elemY)=1)
distinct ptm (if val=0 of elemX then ptm of elemX < ptm of elemY)
This could be done in a traditional way using an external for loop an internal while, but this is not the optimal way to do it.
Trying to find a way to do that, I tried with something like this:
for p in lista:
print([item for item in lista if ((item["sn"] == p["sn"]) & (item["val"] == 0) & (p["val"] == 1) & (
datetime.strptime(item["ptm"], '%d/%m/%Y %H:%M:%S') < datetime.strptime(p["ptm"],'%d/%m/%Y %H:%M:%S')))])
But this does not work (and also is not optimal)
Just build a mapping from (fid,sn,val) onto a list of candidates (the whole dict, its index, or just its ptm (shown below), depending on what output you need). Also check whether any of its opposite numbers (under (fid,sn,!val)) are already present and do the ptm comparison if so:
seen={}
for d in dd:
f=d['fid']; s=d['sn']; v=int(d['val'])
p=datetime.strptime(d['ptm'],'%d/%m/%Y %H:%M:%S')
for p0 in seen.get((f,s,not v),()):
if p0!=p and (p0<p)==v: …
seen.setdefault((f,s,v),[]).append(p)
If you have a large number of values with the same key, you could use a tree to hasten the ptm comparisons, but that seems unlikely here. Using real data types for the individual values, and perhaps a namedtuple to contain them, would of course make this a lot nicer.
Hoping someone can help me out. I've spent the past couple hours trying to solve this, and fair warning, I'm still fairly new to python.
This is a repost of a question I recently deleted. I've misinterpreted my code in the last example.The correct example is:
I have a dictionary, with a list that looks similar to:
dic = [
{
'name': 'john',
'items': ['pants_1', 'shirt_2','socks_3']
},
{
'name': 'bob',
items: ['jacket_1', 'hat_1']
}
]
I'm using .append for both 'name', and 'items', which adds the dic values into two new lists:
for x in dic:
dic_name.append(dic['name'])
dic_items.append(dic['items'])
I need to split the item value using '_' as the delimiter, so I've also split the values by doing:
name, items = [i if i is None else i.split('_')[0] for i in dic_name],
[if i is None else i.split('_')[0] for i in chain(*dic_items)])
None is used in case there is no value. This provides me with a new list for name, items, with the delimiter used. Disregard the fact that I used '_' split for names in this example.
When I use this, the index for name, and item no longer match. Do i need to create the listed items in an array to match the name index, and if so, how?
Ideally, I want name[0] (which is john), to also match items[0] (as an array of the items in the list, so pants, shirt, socks). This way when I refer to index 0 for name, it also grabs all the values for items as index 0. The same thing regarding the index used for bob [1], which should match his items with the same index.
#avinash-raj, thanks for your patience, as I've had to update my question to reflect more closely to the code I'm working with.
I'm reading a little bit between the lines but are you trying to just collapse the list and get rid of the field names, e.g.:
>>> dic = [{'name': 'john', 'items':['pants_1','shirt_2','socks_3']},
{'name': 'bob', 'items':['jacket_1','hat_1']}]
>>> data = {d['name']: dict(i.split('_') for i in d['items']) for d in dic}
>>> data
{'bob': {'hat': '1', 'jacket': '1'},
'john': {'pants': '1', 'shirt': '2', 'socks': '3'}}
Now the data is directly related vs. indirectly related via a common index into 2 lists. If you want the dictionary split out you can always
>>> dic_name, dic_items = zip(*data.items())
>>> dic_name
('bob', 'john')
>>> dic_items
({'hat': '1', 'jacket': '1'}, {'pants': '1', 'shirt': '2', 'socks': '3'})
You need a list of dictionaries because the duplicate keys name and items are overwritten:
items = [[i.split('_')[0] for i in d['items']] for d in your_list]
names = [d['name'] for d in your_list] # then grab names from list
Alternatively, you can do this in one line with the built-in zip method and generators, like so:
names, items = zip(*((i['name'], [j.split('_')[0] for j in i['items']]) for i in dic))
From Looping Techniques in the Tutorial.
for name, items in div.items():
names.append(name)
items.append(item)
That will work if your dict is structured
{'name':[item1]}
In the loop body of
for x in dic:
dic_name.append(dic['name'])
dic_items.append(dic['items'])
you'll probably want to access x (to which the items in dic will be assigned in turn) rather than dic.
I have 2 nested dictionaries in Python that have this format:
1166869: {'probL2': '0.000', 'probL1': '0.000', 'pronNDiff_site': '1.000', 'StateBin': '0', 'chr': 'chrX', 'rangehist': '59254000-59255000', 'start_bin': '59254000', 'countL2': '4', 'countL1': '0'}
1166870: {'probL2': '0.148', 'probL1': '0.000', 'pronNDiff_site': '0.851', 'StateBin': '0', 'chr': 'chr2', 'rangehist': '59254000-59255000', 'start_bin': '59255000', 'countL2': '5', 'countL1': '15'}
1166871: {'probL2': '0.000', 'probL1': '0.000', 'pronNDiff_site': '1.000', 'StateBin': '0', 'chr': 'chrY', 'rangehist': '59290000-59291000', 'start_bin': '59290000', 'countL2': '1', 'countL1': '2'}
where 1166869, 1166870 and 1166871 represent a line in a file from where I read the data, and the rest of the keys are the data itself.
Now I want to make a list where I store all the different values in the key "chr" because there are some repeated ones.
How can I go through the dictionary and make the comparison between the 2 values? This code is not working:
for k in range(len(file_dict)):
for j in range(len(file_dict)-1):
if (file_dict[j]["chr"] != file_dict[k]["chr"]):
list_chr.append(file_dict[j]["chr"])
Use a set, and just all the items in one go:
chr = { v['chr'] for v in file_dict.itervalues() }
This uses a set comprehension to generate your set in one line of code.
Set comprehensions were introduced in Python 2.7; in earlier versions use:
chr = set(v['chr'] for v in file_dict.itervalues())
In Python 3, you'd need to replace .itervalues() by .values().
Your own code doesn't work because python dictionaries are not lists; you don't retrieve values by index, but by key. You'd have to change it to:
for key in file_dict:
for other_key in file_dict:
if key == other_key:
continue
if file_dict[key]['chr'] != file_dict[otherkey]['chr']:
list_chr.append(filed_dict[key]['chr'])
but that is really inefficient, not to mention incorrect.
how about something along the lines of:
list_chr = list(set([val['chr'] for val in file_dict.values()]))
how does this work?
first a list comprehension gets all the chr entries in the inner dict
these are then converted to a set, such that there are no duplicate entries
these are then converted to a list if that's the format you prefere
please note that maybe you really want to use a set, then the look up time is O(1) instead of O(n)