This question already has answers here:
How to keep keys/values in same order as declared?
(13 answers)
Closed 4 years ago.
I am reading a dictionary in python2.6 as below
I know Python3.6 will read the dictionary in the same order it is declared, but i need to achieve this in Python2.6 (OrderedDict is also not available in Python2.6)
numbermap = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
>>> for k, v in numbermap.iteritems():
... print(k,v)
...
('four', 4)
('three', 3)
('five', 5)
('two', 2)
('one', 1)
I want the output to be
('one',1)
('two', 2)
('three', 3)
('four', 4)
('five', 5)
I need to write as I read the dictionary. Any ideas to achieve this in Python 2.6?
There are many practices available for the sorting dictionary. You can check below examples.
First example:
>>> import operator
>>> numbermap = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
>>> sorted_maps = sorted(numbermap.items(), key=operator.itemgetter(1))
>>> print(sorted_maps)
[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
Second example:
>>> import collections
>>> sorted_maps = collections.OrderedDict(numbermap)
>>> print(sorted_maps)
OrderedDict([('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)])
It seems that you want an ordered dictionary. If you can use Python 2.7, look up collections.OrderedDict: https://docs.python.org/2/library/collections.html#collections.OrderedDict
If you have to stick with 2.6, there are some suggestions here: https://stackoverflow.com/a/1617087/3061818 (but you should probably head over to Dictionaries: How to keep keys/values in same order as declared?)
1 reverse the key value,
2 sort the new key which is the value
my solution is to sort the keys
sounds like cheating, but works:
first call something to reverse dict
for i in sort(numbermap.keys()):
print(i,numbermap[i])
Related
I'm writing this question despite the many answers on stackoverflow as the solutions did not work for my problem.
I have 2 Lists, List1 and List2. When I dict(zip(List1,List2)) the order of the elements inside the dictionary are disturbed.
print s_key
print value
sorted_dict = {k: v for k,v in zip(s_key,value)}
another_test = dict(zip(s_key,value))
print sorted_dict
print another_test
print zip(s_key,value))
Terminal :
[2, 1, 3]
[31, 12, 5]
{1: 12, 2: 31, 3: 5}
{1: 12, 2: 31, 3: 5}
[(2, 31), (1, 12), (3, 5)]
I was under the impression that the [(2, 31), (1, 12), (3, 5)] would be converted to a dict
Any help to understand where or what I'm doing wrong would help! Thanks!
a=[2, 1, 3]
b=[31, 12, 5]
from collections import OrderedDict
print(OrderedDict(zip(a,b)))
You cannot sort a dictionary, in your case if you wanted to display sorted key/values of your dictionary you can convert it to a list of tuples as you have and sort it by whichever element you want. In the code below it creates a list of tuples and sorts by the first element in the tuples:
l1,l2=[2, 1, 3],[31, 12, 5]
print ([(one,two) for (one,two) in
sorted(zip(l1,l2),key=lambda pair: pair[0])])
prints:
[(1, 12), (2, 31), (3, 5)]
shoutout to Sorting list based on values from another list? for the help
Either that or create a list of the dictionaries keys and sort the list then loop through the list and call each key
Or use ordered dict as others have pointed out
Consider I have a tuple in Python
numbers = (('One', 1), ('Two', 2), ('Three', 3), ('Four', 4))
I want to create a numbers_dict in dictionary
numbers_dict = {}
for number in numbers:
numbers_dict[number[0]] = number[1]
and so I get
numbers_dict = {
'One': 1,
'Two': 2,
'Three': 3,
'Four': 4,
}
Can I do something simpler using the syntax
numbers_dict = [n[0] : n[1] for n in numbers]
?
Just pass numbers directly to the dict() type:
numbers_dict = dict(numbers)
From the documentation:
If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value.
Your numbers tuple is such an iterable, and each element in it is a (key, value) pair.
Demo:
>>> numbers = (('One', 1), ('Two', 2), ('Three', 3), ('Four', 4))
>>> dict(numbers)
{'One': 1, 'Four': 4, 'Three': 3, 'Two': 2}
You could use a dictionary comprehension too, but that's really overkill here; only use that when you do something more meaningful for each key or value. But for completeness sake, that'd look like this:
numbers_dict = {k: v for k, v in numbers}
I have a dictionary made by:
d={'name':(values), (values), (values), 'name2':(values),(values), ...ecc}
so values are tuples.
I want to check if some tuples associated to a value are the same.
How you define "the same"? Does (1, 2) should be "the same" as (2, 1)?
If (1, 2) isn't "the same" as (2, 1) you can simply iterate over the values and check if they are equal with the == operator.
If (1, 2) is "the same" as (2, 1) you can sort them (or simply turn them into a set) and then do the same as above.
EDIT: Since you clarified that you want the first behavior, you can create a new dictionary with dictionary comprehension (assuming you are using Python 2.7 or above) and turning each list of tuples to a set of tuples:
d = {'a': [(1,1), (1,1), (1,2)], 'b': [(3,3), (2,5), (3,3)]}
new_d = { k:list(set(v)) for k,v in d.iteritems() }
>> {'a': [(1, 2), (1, 1)], 'b': [(2, 5), (3, 3)]}
I am trying to populate a dictionary in python but I would like to preserve the order of the keys as they get in - exactly FIFO like a list would do it.
For example,
I read a file called animals.txt containing the following information:
animal\tconservation_status\n
dog\tdomesticated\n
tiger\tEN\n
panda\tEN\n
I.e.,
animals = {'dog':'dom','tiger':'EN', 'panda':'EN'}
>>> for el in animals:
... print el
...
tiger
dog
panda
And in a FIFO SHOULD have been dog, tiger, panda as they come out...
When I read it into a dictionary the order will not be preserved. I would like the order to be preserved such that when I do a for loop the FIRST IN is the FIRST OUT.
I.e.,
dog, then tiger, then panda.
Is there a nice way to do this without having to keep an external index or a more complex dictionary structure? Not sure, sorry for my naivity here...
Yes. You use a collections.OrderedDict instead of a regular dictionary.
>>> d = OrderedDict((x,x) for x in reversed(range(10)) )
>>> d
OrderedDict([(9, 9), (8, 8), (7, 7), (6, 6), (5, 5), (4, 4), (3, 3), (2, 2), (1, 1), (0, 0)])
>>> regular = dict((x,x) for x in reversed(range(10)))
>>> regular
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
Notice that the OrderedDict preserves the order whereas the regular dict does not.
>>> OrderedDict([('dog','dom'),('tiger','EN'), ('panda','EN')])
OrderedDict([('dog', 'dom'), ('tiger', 'EN'), ('panda', 'EN')])
Another gotcha is that you need to pass items to the constructor (or .update) in a way that preserves order. In other words, you can't pass keyword args to the constructor and expect order to be preserved:
>>> OrderedDict(dog='dom',tiger='EN',panda='EN') #doesn't preserve order
OrderedDict([('tiger', 'EN'), ('panda', 'EN'), ('dog', 'dom')])
I have a list
l=[(1,2),(1,6),(3,4),(3,6),(1,4),(4,3)]
I want to return a list that contains lists by the first number in each tuple.
Something like this:
[[2,4,6],[4,6],[3]]
To make a program that iterates on list and writing a whole function that does it is easy.
I want to find a oneliner - python way of doing it.
Any ideas?
>>> from itertools import groupby
>>> from operator import itemgetter
>>> L = [(1,2), (1,6), (3,4), (3,6), (1,4), (4,3)]
>>> [[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
[[2, 4, 6], [4, 6], [3]]
Explanation
This works by using itertools.groupby. groupby finds consecutive groups in an iterable, returning an iterator through key, group pairs.
The argument given to groupby is a key function, itemgetter(0) which is called for each tuple, returning the first item as the key to groupby.
groupby groups elements in their original order so if you want to group by the first number in the list, it must first be sorted so groupby can go through the first numbers in ascending order and actually group them.
>>> sorted(L)
[(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (4, 3)]
There is the sorted list where you can clearly see the groups that will be created if you look back to the final output. Now you can use groupby to show the key, group pairs.
[(1, <itertools._grouper object at 0x02BB7ED0>), (3, <itertools._grouper object at 0x02BB7CF0>), (4, <itertools._grouper object at 0x02BB7E30>)]
Here are the sorted items grouped by the first number. groupby returns the group for each key as an iterator, this is great and very efficient but for this example we will just convert it to a list to make sure it's working properly.
>>> [(k, list(v)) for k,v in groupby(sorted(L), itemgetter(0))]
[(1, [(1, 2), (1, 4), (1, 6)]), (3, [(3, 4), (3, 6)]), (4, [(4, 3)])]
That is almost the right thing but the required output shows only the 2nd number in the groups in each list. So the following achieves the desired result.
[[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
l = [(1, 2), (1, 6), (3, 4), (3, 6), (1, 4), (4, 3)]
d = {}
for (k, v) in l:
d.setdefault(k, []).append(v)
print d.values()
I know it's not a one liner, but perhaps it's easier to read than a one liner.