2008-09-03 55 views
12

我有一个方法在我的Python代码中返回一个元组 - 从SQL查询中得到一行。假设它有三个字段:(jobId,label,username)在Python中分割元组 - 最佳实践?

为了便于在函数之间传递它,我一直将整个元组作为一个名为'job'的变量传递。然而,最终,我想获得这些位,所以我一直在使用这样的代码: (jobId,label,username)= job

但是,我意识到这是一个维护噩梦,因为现在我永远不会将新字段添加到结果集,而不会破坏我现有的所有代码。我应该如何写这个?

这里是我的两个最好的猜测: (的jobId,标签,用户名)=(工作[0],工作[1],工作[2]) ......但是,这并不很好,当你有规模15 ... 20个字段

或将SQL查询的结果直接转换为字典并将其传递给字典(我无法控制它将元素作为元组启动的事实,这对我来说是固定的)

回答

13

我想说,字典绝对是最好的方式来做到这一点。它很容易扩展,允许为每个值赋予一个明智的名称,并且Python具有大量用于使用和操作字典的内置语言功能。如果您以后需要添加更多字段,则需要更改的是将元组转换为字典的代码以及实际使用新值的代码。

例如:

job={} 
job['jobid'], job['label'], job['username']=<querycode> 
+0

另请参阅http://code.activestate.com/recipes/81252/ – Jay 2008-12-22 20:23:35

0

有了一个元组将始终是一个麻烦添加或更改字段。你说得对,字典会好很多。

如果你想要一些稍微友好的语法,你可能想看看关于一个简单的类似于结构的对象的回答this question。你可以把物体周围的这样,说job,更方便地访问它的字段不是一个元组或字典:

job.jobId, job.username = jobId, username 
3

也许这就是矫枉过正的情况,但我会很想创建一个“工作“这个类将这个元组作为它的构造函数参数,并且具有它们各自的属性。然后我会传递这个类的实例。

2

我会用字典。您可以将元组这种方式转换成词典:

values = <querycode> 
keys = ["jobid", "label", "username"] 
job = dict([[keys[i], values [i]] for i in xrange(len(values))]) 

这将首先创建一个数组[ “作业ID”,VAL1],[ “标签”,值2],[ “用户名”,VAL3]和然后将其转换为字典。如果结果顺序或计数发生变化,您只需更改键列表以匹配新结果。

PS自己还是很新鲜的,所以可能有更好的方法。

+2

请参阅Aaron Maenpaa回答Zip。当一个常见的Python新手错误使用列表解析时,zip就足够了。 – 2009-07-18 13:17:19

-2

如何:

class TypedTuple: 
    def __init__(self, fieldlist, items): 
     self.fieldlist = fieldlist 
     self.items = items 
    def __getattr__(self, field): 
     return self.items[self.fieldlist.index(field)] 

你可以再做:

j = TypedTuple(["jobid", "label", "username"], job) 
print j.jobid 

它应该是容易掉self.fieldlist.index(field)用字典查找稍后...只需编辑您的__init__方法!像Staale那样。

13

@Staale

有一个更好的办法:

job = dict(zip(keys, values)) 
+0

这也是非常可维护的代码,唯一的“问题”是重建代码来处理字典。 – 2009-07-18 13:16:36

2

一个老问题,但由于没有人提到它,我会从Python食谱补充一点:

Recipe 81252: Using dtuple for Flexible Query Result Access

这个配方是专门为处理数据库结果而设计的,dtuple解决方案允许您通过名称或索引号访问结果。这避免了必须通过非常难以维护的下标访问所有内容,正如您的问题所述。

5

这是一个老问题,但...

我建议在这种情况下,使用一个名为元组:collections.namedtuple

这是一部分,特别是,你会发现有用:

子类化对于添加新的存储字段没有用。相反,只需从_fields属性创建一个新的命名元组类型即可。

+2

其他好处:* namedtuple *方法使用比字典更少的内存,并且它支持用于更新值的\ _replace()方法。 – 2012-11-28 06:47:58

0

如果您使用的是MySQLdb包,您可以设置游标对象以返回字典而不是元组。

import MySQLdb, MySQLdb.cursors 
conn = MySQLdb.connect(..., cursorclass=MySQLdb.cursors.DictCursor) 
cur = conn.cursor() # a DictCursor 
cur2 = conn.cursor(cursorclass=MySQLdb.cursors.Cursor) # a "normal" tuple cursor