Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

confusing python urlencode order

okay, so according to http://docs.python.org/library/urllib.html

"The order of parameters in the encoded string will match the order of parameter tuples in the sequence."

except when I try to run this code:

import urllib
values ={'one':'one',
         'two':'two',
         'three':'three',
         'four':'four',
         'five':'five',
         'six':'six',
         'seven':'seven'}
data=urllib.urlencode(values)
print data

outputs as ...

seven=seven&six=six&three=three&two=two&four=four&five=five&one=one

7,6,3,2,4,5,1?

That doesn't look like the order of my tuples.

like image 375
Neil Turley Avatar asked Jul 27 '10 20:07

Neil Turley


2 Answers

Dictionaries are inherently unordered because of the way they are implemented. If you want them to be ordered, you should use a list of tuples instead (or a tuple of lists, or a tuple of tuples, or a list of lists...):

values = [ ('one', 'one'), ('two', 'two') ... ]
like image 200
Donald Miner Avatar answered Oct 10 '22 23:10

Donald Miner


Just in case someones arrives here like me searching for a way to get deterministic results from urlencode, to encode the values alphabetically you can do it like this:

from urllib.parse import urlencode
values ={'one':'one',
         'two':'two',
         'three':'three',
         'four':'four',
         'five':'five',
         'six':'six',
         'seven':'seven'}
sorted_values = sorted(values.items(), key=lambda val: val[0])
data=urlencode(sorted_values)
print(data)
#> 'five=five&four=four&one=one&seven=seven&six=six&three=three&two=two'
like image 30
Zequez Avatar answered Oct 10 '22 23:10

Zequez