Print original input order of dictionary in python - python

How do I print out my dictionary in the original order I had set up?
If I have a dictionary like this:
smallestCars = {'Civic96': 12.5, 'Camry98':13.2, 'Sentra98': 13.8}
and I do this:
for cars in smallestCars:
print cars
it outputs:
Sentra98
Civic96
Camry98
but what I want is this:
Civic96
Camry98
Sentra98
Is there a way to print the original dictionary in order without converting it to a list?

A regular dictionary doesn't have order. You need to use the OrderedDict of the collections module, which can take a list of lists or a list of tuples, just like this:
import collections
key_value_pairs = [('Civic86', 12.5),
('Camry98', 13.2),
('Sentra98', 13.8)]
smallestCars = collections.OrderedDict(key_value_pairs)
for car in smallestCars:
print(car)
And the output is:
Civic96
Camry98
Sentra98

Dictionaries are not required to keep order. Use OrderedDict.

>>> for car in sorted(smallestCars.items(),key=lambda x:x[1]):
... print car[0]
...
Civic96
Camry98
Sentra98

When you create the dictionary, python doesn't care about in what order you wrote the elements and it won't remember the order after the object is created. You cannot expect it(regular dictionary) to print in the same order. Changing the structure of your code is the best option you have here and the OrderedDict is a good option as others stated.

You can use a tuple (nested) array to do this:
smallestCars = [['Civic86', 12.5],
['Camry98', 13.2],
['Sentra98', 13.8]]
for car, size in smallestCars:
print(car, size)
# ('Civic86', 12.5)
# ('Camry98', 13.2)
# ('Sentra98', 13.8)

Related

Manipulating a list of dictionaries

I successfully imported from the web this json file, which looks like:
[{"h_mag":"19.7","i_deg":"9.65","moid_au":"0.035"},{"h_mag":"20.5","i_deg":"14.52","moid_au":"0.028"},
etc ...
I want to extract the values of the key moid_au, later compare moid_au with the key values of h_mag.
This works: print(data[1]['moid_au']), but if I try to ask all the elements of the list it won't, I tried: print(data[:]['moid_au']).
I tried iterators and a lambda function but still has not work yet, mostly because I'm new in data manipulation. It works when I have one dictionary, not with a list of dictionaries.
Thanks in advance for other tips. Some links were confusing.
Sounds like you are using lambda wrong because you need map as well:
c = [{"h_mag":"19.7","i_deg":"9.65","moid_au":"0.035"},{"h_mag":"20.5","i_deg":"14.52","moid_au":"0.028"}]
list(map(lambda rec: rec.get('moid_au'), c))
['0.035', '0.028']
Each lambda grabs a record from your list and you map your function to that.
Using print(data[:]['moid_au']) equals to print(data['moid_au']), and you can see that it won't work, as data has no key named 'moid_au'.
Try working with a loop:
for item in data:
print(item['moid_au'])
using your approach to iterate over the whole array to get all the instances of a key,this method might work for you
a = [data[i]['moid_au']for i in range(len(data))]
print(a)
In which exact way do you want to compare them?
Would it be useful getting the values in a way like this?
list_of_dicts = [{"h_mag":"19.7","i_deg":"9.65","moid_au":"0.035"}, {"h_mag":"20.5","i_deg":"14.52","moid_au":"0.028"}]
mod_au_values = [d["moid_au"] for d in list_of_dicts]
h_mag_values = [d["h_mag"] for d in list_of_dicts]
for key, value in my_list.items ():
print key
print value
for value in my_list.values ():
print value
for key in my_list.keys():
print key

Add object to start of dictionary

I am making a group chatting app and I have images associated with the users, so whenever they say something, their image is displayed next to it. I wrote the server in python and the client will be an iOS app. I use a dictionary to store all of the message/image pairs. Whenever my iOS app sends a command to the server (msg:<message), the dictionary adds the image and message to the dictionary like so:dictionary[message] = imageName, which is converted to lists then strings to be sent off in a socket. I would like to add the incoming messages to the start of the dictionary, instead of the end. Something like
#When added to end:
dictionary = {"hello":image3.png}
#new message
dictionary = {"hello":image3.png, "i like py":image1.png}
#When added to start:
dictionary = {"hello":image3.png}
#new message
dictionary = {"i like py":image1.png, "hello":image3.png}
Is there any way to add the object to the start of the dictionary?
For the use case described it sounds like a list of tuples would be a better data structure.
However, it has been possible to order a dictionary since Python 3.7. Dictionaries are now ordered by insertion order.
To add an element anywhere other than the end of a dictionary, you need to re-create the dictionary and insert the elements in order. This is pretty simple if you want to add an entry to the start of the dictionary.
# Existing data structure
old_dictionary = {"hello": "image3.png"}
# Create a new dictionary with "I like py" at the start, then
# everything from the old data structure.
new_dictionary = {"i like py": "image1.png"}
new_dictionary.update(old_dictionary)
# new_dictionary is now:
# {'i like py': 'image1.png', 'hello': 'image3.png'}
(python3) good example from Manjeet on geeksforgeeks.org
test_dict = {"Gfg" : 5, "is" : 3, "best" : 10}
updict = {"pre1" : 4, "pre2" : 8}
# ** operator for packing and unpacking items in order
res = {**updict, **test_dict}
First of all it doesn't added the item at the end of dictionary because dictionaries use hash-table to storing their elements and are unordered. if you want to preserve the order you can use collections.OrderedDict.but it will appends the item at the end of your dictionary. One way is appending that item to the fist of your items then convert it to an Orderd:
>>> from collections import OrderedDict
>>> d=OrderedDict()
>>> for i,j in [(1,'a'),(2,'b')]:
... d[i]=j
...
>>> d
OrderedDict([(1, 'a'), (2, 'b')])
>>> d=OrderedDict([(3,'t')]+d.items())
>>> d
OrderedDict([(3, 't'), (1, 'a'), (2, 'b')])
Also as another efficient way if it's not necessary to use a dictionary you can use a deque that allows you to append from both side :
>>> from collections import deque
>>> d=deque()
>>> d.append((1,'a'))
>>> d.append((4,'t'))
>>> d
deque([(1, 'a'), (4, 't')])
>>> d.appendleft((8,'p'))
>>> d
deque([(8, 'p'), (1, 'a'), (4, 't')])
I am not sure that a dictionary is the best data structure for your data, but you may find useful collections.OderedDict. It is basically a dictionary that remembers the order of keys added to the dictionary in a FIFO fashion (which is the opposite of what you need).
If you want to retrieve all your items starting from the most recent one, you can use reversed() to reverse dictionary iterators. You can also use the method popitem() to retrieve (and remove) from the dictionary the key-value pair you last entered.
Link to the docs: https://docs.python.org/2/library/collections.html#collections.OrderedDict
As others have pointed out, there is no concept of "order" in a standard dict. Although you can use an OrderedDict to add ordering behavior, this brings other considerations -- unlike a normal dict, isn't a portable data structure (e.g. dumping to JSON then reloading does not preserve order) -- and isn't available in the standard library for all versions of Python.
You might be better off using a sequential key in a standard dict -- a count-up index, or time stamp -- to keep things simple.
As others have pointed out, there is no "order" in a dictionary. However, if you are like me and just need a temporary (/ hacky) workaround that works for your purposes. There is a way to do this.
You can iterate the dictionary, and append the item at the beginning of the iteration process. This seemed to work for me.
The relevant part is where new_fields is declared. I am including the rest for context.
userprofile_json = Path(__file__).parents[2] / f"data/seed-data/user-profile.json"
with open(userprofile_json) as f:
user_profiles = json.load(f)
for user_profile in user_profiles:
new_fields = {
'user': user_profile['fields']['username'],
}
for k, v in user_profile['fields'].items():
new_fields[k] = v
user_profile['fields'] = new_fields
with open(userprofile_json, 'w') as f:
json.dump(user_profiles, f, indent=4)

Pythonic way to get the index of element from a list of dicts depending on multiple keys

I am very new to python, and I have the following problem. I came up with the following solution. I am wondering whether it is "pythonic" or not. If not, what would be the best solution ?
The problem is :
I have a list of dict
each dict has at least three items
I want to find the position in the list of the dict with specific three values
This is my python example
import collections
import random
# lets build the list, for the example
dicts = []
dicts.append({'idName':'NA','idGroup':'GA','idFamily':'FA'})
dicts.append({'idName':'NA','idGroup':'GA','idFamily':'FB'})
dicts.append({'idName':'NA','idGroup':'GB','idFamily':'FA'})
dicts.append({'idName':'NA','idGroup':'GB','idFamily':'FB'})
dicts.append({'idName':'NB','idGroup':'GA','idFamily':'FA'})
dicts.append({'idName':'NB','idGroup':'GA','idFamily':'FB'})
dicts.append({'idName':'NB','idGroup':'GB','idFamily':'FA'})
dicts.append({'idName':'NB','idGroup':'GB','idFamily':'FB'})
# let's shuffle it, again for example
random.shuffle(dicts)
# now I want to have for each combination the index
# I use a recursive defaultdict definition
# because it permits creating a dict of dict
# even if it is not initialized
def tree(): return collections.defaultdict(tree)
# initiate mapping
mapping = tree()
# fill the mapping
for i,d in enumerate(dicts):
idFamily = d['idFamily']
idGroup = d['idGroup']
idName = d['idName']
mapping[idName][idGroup][idFamily] = i
# I end up with the mapping providing me with the index within
# list of dicts
Looks reasonable to me, but perhaps a little too much. You could instead do:
mapping = {
(d['idName'], d['idGroup'], d['idFamily']) : i
for i, d in enumerate(dicts)
}
Then access it with mapping['NA', 'GA', 'FA'] instead of mapping['NA']['GA']['FA']. But it really depends how you're planning to use the mapping. If you need to be able to take mapping['NA'] and use it as a dictionary then what you have is fine.

Converting data into dictionary of Dictionaries in python

I am reading a file in python using a key value pair, for example
Mac:aaaa
IP:bbbbb
Name:dddd
Mac:wwwww
IP:fffff
Name:sssss
Mac:hhhh
IP:ddd
Name:fff
so, my query is, I need to build a dictionary of dictionaries for the above data so as to format it as json.
I assume you mean a list of dictionaries, not a dictionary of dictionaries
from operator import methodcaller
fdata = open("data.txt").read().split()
split2 = methodcaller("split",":")
print map(dict, zip(*[iter(map(split2, fdata))]*3))
is a fun way to do it ;)
however if you did want a dictionary of dictionaries as your title suggests you can simply
dict(enumerate(map(dict, zip(*[iter(map(split2, fdata.split()))]*3))))
[edited to be more pep-8 compliant :P ]

How to append to a list in a dictionary?

Can I append to a list in a dictionary?
test = {'food' : 'apple'}
Is there a command to add 'banana' and turn it into
test = { 'food': ['apple','banana'] }
Thank you
No, since it isn't a list in the first place.
test['food'] = [test['food'], 'banana']
You need to create a dict where the values are lists:
test = {'food' : ['apple']}
test['food'].append('banana')
The simplest solution would just be to just make the value of your hash a list, that may contain just one element. Then for example, you might have something like this:
test = {'food' : ['apple']}
test['food'].append('banana')
I'd recommend using a defaultdict in this case, it's pretty straightforward to deal with dictionaries of lists, since then you don't need two separate cases every time you modify an entry:
import collections
test = collections.defaultdict(list)
test['food'].append('apple')
test['food'].append('banana')
print test
# defaultdict(<type 'list'>, {'food': ['apple', 'banana']})

Categories