<p>I have a method in my Python code that returns a tuple - a row from a SQL query. Let's say it has three fields: (jobId, label, username)</p>

<p>For ease of passing it around between functions, I've been passing the entire tuple as a variable called 'job'. Eventually, however, I want to get at the bits, so I've been using code like this:
(jobId, label, username) = job</p>

<p>I've realised, however, that this is a maintenance nightmare, because now I can never add new fields to the result set without breaking all of my existing code. How should I have written this?</p>

<p>Here are my two best guesses:
(jobId, label, username) = (job[0], job[1], job[2])
...but that doesn't scale nicely when you have 15...20 fields</p>

<p>or to convert the results from the SQL query to a dictionary straight away and pass that around (I don't have control over the fact that it starts life as a tuple, that's fixed for me)</p>

[{'answer_id': 41707, 'author': 'Chris Upchurch', 'author_id': 2600, 'author_profile': 'https://Stackoverflow.com/users/2600', 'pm_score': 5, 'selected': True, 'text': "<p>I'd say that a dictionary is definitely the best way to do it.  It's easily extensible, allows you to give each value a sensible name, and Python has a lot of built-in language features for using and manipulating dictionaries.  If you need to add more fields later, all you need to change is the code that converts the tuple to a dictionary and the code that actually makes use of the new values.</p>\n\n<p>For example:</p>\n\n<pre><code>job={}\njob['jobid'], job['label'], job['username']=&lt;querycode&gt;\n</code></pre>\n"}, {'answer_id': 41709, 'author': 'dF.', 'author_id': 3002, 'author_profile': 'https://Stackoverflow.com/users/3002', 'pm_score': 0, 'selected': False, 'text': '<p>With a tuple it will always be a hassle to add or change fields. You\'re right that a dictionary will be much better. </p>\n\n<p>If you want something with slightly friendlier syntax you might want to take a look at the answers <a href="https://stackoverflow.com/questions/35988/c-like-structures-in-python">this question</a> about a simple \'struct-like\' object. That way you can pass around an object, say <code>job</code>, and access its fields even more easily than a tuple or dict:</p>\n\n<pre><code>job.jobId, job.username = jobId, username\n</code></pre>\n'}, {'answer_id': 41721, 'author': 'Ryan Duffield', 'author_id': 2696, 'author_profile': 'https://Stackoverflow.com/users/2696', 'pm_score': 2, 'selected': False, 'text': '<p>Perhaps this is overkill for your case, but I would be tempted to create a "Job" class that takes the tuple as its constructor argument and has respective properties on it.  I\'d then pass instances of this class around instead.</p>\n'}, {'answer_id': 41723, 'author': 'Staale', 'author_id': 3355, 'author_profile': 'https://Stackoverflow.com/users/3355', 'pm_score': 2, 'selected': False, 'text': '<p>I would use a dictionary. You can convert the tuple to a dictionary this way:</p>\n\n<pre><code>values = &lt;querycode&gt;\nkeys = ["jobid", "label", "username"]\njob = dict([[keys[i], values [i]] for i in xrange(len(values ))])\n</code></pre>\n\n<p>This will first create an array [["jobid", val1], ["label", val2], ["username", val3]] and then convert that to a dictionary. If the result order or count changes, you just need to change the list of keys to match the new result.</p>\n\n<p>PS still fresh on Python myself, so there might be better ways off doing this.</p>\n'}, {'answer_id': 41730, 'author': 'Daren Thomas', 'author_id': 2260, 'author_profile': 'https://Stackoverflow.com/users/2260', 'pm_score': -1, 'selected': False, 'text': '<p>How about this:</p>\n\n<pre><code>class TypedTuple:\n    def __init__(self, fieldlist, items):\n       self.fieldlist = fieldlist\n       self.items = items\n    def __getattr__(self, field):\n       return self.items[self.fieldlist.index(field)]\n</code></pre>\n\n<p>You could then do:</p>\n\n<pre><code>j = TypedTuple(["jobid", "label", "username"], job)\nprint j.jobid\n</code></pre>\n\n<p>It should be easy to swap <code>self.fieldlist.index(field)</code> with a dictionary lookup later on... just edit your <code>__init__</code> method! Something like Staale does.</p>\n'}, {'answer_id': 41846, 'author': 'Aaron Maenpaa', 'author_id': 2603, 'author_profile': 'https://Stackoverflow.com/users/2603', 'pm_score': 4, 'selected': False, 'text': '<p>@Staale</p>\n\n<p>There is a better way:</p>\n\n<pre><code>job = dict(zip(keys, values))\n</code></pre>\n'}, {'answer_id': 387242, 'author': 'Jay', 'author_id': 20840, 'author_profile': 'https://Stackoverflow.com/users/20840', 'pm_score': 2, 'selected': False, 'text': '<p>An old question, but since no one mentioned it I\'ll add this from the Python Cookbook: </p>\n\n<p><a href="http://code.activestate.com/recipes/81252/" rel="nofollow noreferrer">Recipe 81252: Using dtuple for Flexible Query Result Access </a></p>\n\n<p>This recipe is specifically designed for dealing with database results, and the dtuple solution allows you to access the results by name OR index number. This avoids having to access everything by subscript which is very difficult to maintain, as noted in your question.</p>\n'}, {'answer_id': 1144246, 'author': 'JAB', 'author_id': 138772, 'author_profile': 'https://Stackoverflow.com/users/138772', 'pm_score': 3, 'selected': False, 'text': '<p>This is an old question, but...</p>\n\n<p>I\'d suggest using a named tuple in this situation: <a href="http://docs.python.org/3.1/library/collections.html#collections.namedtuple" rel="noreferrer">collections.namedtuple</a></p>\n\n<p>This is the part, in particular, that you\'d find useful:</p>\n\n<blockquote>\n  <p>Subclassing is not useful for adding new, stored fields. Instead, simply create a new named tuple type from the _fields attribute.</p>\n</blockquote>\n'}, {'answer_id': 2609123, 'author': 'jpkotta', 'author_id': 245173, 'author_profile': 'https://Stackoverflow.com/users/245173', 'pm_score': 0, 'selected': False, 'text': '<p>If you\'re using the MySQLdb package, you can set up your cursor objects to return dicts instead of tuples.</p>\n\n<pre><code>import MySQLdb, MySQLdb.cursors\nconn = MySQLdb.connect(..., cursorclass=MySQLdb.cursors.DictCursor)\ncur = conn.cursor() # a DictCursor\ncur2 = conn.cursor(cursorclass=MySQLdb.cursors.Cursor) # a "normal" tuple cursor\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/41701', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4397/']