How to stop Python parse_qs from parsing single values into lists?

PythonPython 2.6

Python Problem Overview


In python 2.6, the following code:

import urlparse
qsdata = "test=test&test2=test2&test2=test3"
qs = urlparse.parse_qs(qsdata)
print qs

Gives the following output:

{'test': ['test'], 'test2': ['test2', 'test3']}

Which means that even though there is only one value for test, it is still being parsed into a list. Is there a way to ensure that if there's only one value, it is not parsed into a list, so that the result would look like this?

{'test': 'test', 'test2': ['test2', 'test3']}

Python Solutions


Solution 1 - Python

A sidenote for someone just wanting a simple dictionary and never needing multiple values with the same key, try:

dict(urlparse.parse_qsl('foo=bar&baz=qux'))

This will give you a nice {'foo': 'bar', 'baz': 'qux'}. Please note that if there are multiple values for the same key, you'll only get the last one.

Solution 2 - Python

You could fix it afterwards...

import urlparse
qsdata = "test=test&test2=test2&test2=test3"
qs = dict( (k, v if len(v)>1 else v[0] ) 
           for k, v in urlparse.parse_qs(qsdata).iteritems() )
print qs

However, I don't think I would want this. If a parameter that is normally a list happens to arrive with only one item set, then I would have a string instead of the list of strings I normally receive.

Solution 3 - Python

Expanding on @SingleNegationElimination answer a bit. If you do something like this, you can use only the last instance of a query parameter.

from urllib.parse import parse_qs
qsdata = "test=test&test2=test2&test2=test3"
dict((k, v[-1] if isinstance(v, list) else v)
      for k, v in parse_qs(qsdata).items())

# Returns: {'test': 'test', 'test2': 'test3'}

Or you can retain only the first instance of a url parameter with the following:

from urllib.parse import parse_qs
qsdata = "test=test&test2=test2&test2=test3"
dict((k, v[0] if isinstance(v, list) else v)
      for k, v in parse_qs(qsdata).items())

# Returns: {'test': 'test', 'test2': 'test2'}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShabbyrobeView Question on Stackoverflow
Solution 1 - PythontuomassaloView Answer on Stackoverflow
Solution 2 - PythonSingleNegationEliminationView Answer on Stackoverflow
Solution 3 - PythonJoe JView Answer on Stackoverflow