I have a dictionary {'16022000': 5172863.79, '21349000': 264853.56, '21362000': -5437717.35}
and created 4 lists for positive/negative key/values:
list({(g) for g, v in gv.items() if v >= 0})
list({(g) for g, v in gv.items() if v <= 0})
list({(v) for g, v in gv.items() if v >= 0})
list({(v) for g, v in gv.items() if v <= 0})
The results I got when printing the lists were:
['16022000', '21349000']
[264853.56, 5172863.79]
['21362000']
[-5437717.35]
Expecting:
['16022000', '21349000']
[5172863.79, 264853.56]
It seemed that list sorted numbers by value. How can I prevent that?
CodePudding user response:
Problem 1
Standard Python dict
has no order; so no, you can't preserve the order, as there is none.
Since Python 3.7 dict
has order. (Thankyou snakecharmerb, Vikash)
Problem 2
You are using "set comprehension" syntax: {a for b in thing if condition}
Sets similarly have no order.
Solution
Use an OrderedDict
instead of a dict
.
Use a list comprehension instead of a set comprehension.
gv = {'16022000': 5172863.79, '21349000': 264853.56, '21362000': -5437717.35})
[g for g, v in gv.items() if v >= 0]
[g for g, v in gv.items() if v <= 0]
[v for g, v in gv.items() if v >= 0]
[v for g, v in gv.items() if v <= 0]
Remark
The only reason the order would matter to you is if you were going to pair the numbers back up after the fact. Have you considered:
[(g, v) for g, v in gv.items() if v >= 0]
or, as a dictionary
{g: v for g, v in gv.items() if v >= 0]
CodePudding user response:
I don't know if you noticed it, but you are actually storing the resultant elements in a set which you are then converting to a list.
Let me break down the code. Let's take line 3 as an example.
print(list({(v) for g, v in gv.items() if v >= 0}))
Now if you remove the list() constructor, you will notice the obvious.
print({(v) for g, v in gv.items() if v >= 0})
Output:
{264853.56, 5172863.79}
You can clearly see that the output is a set.
Why I'm telling you this is because sets are actually unordered. They store every elements in a random order. So, the output is in an order which dosen't make any sense.
So, to fix this problem, try not to store everything in a set, rather store it in a list itself.
print([v for g, v in gv.items() if v >= 0])
Now, the output will be more understandable:
[5172863.79, 264853.56]