在Python中拆分元组-最佳做法?
我的Python代码中有一个方法,可以从SQL查询返回一个元组。假设它具有三个字段:(jobId,label,username)
为了便于在函数之间传递它,我将整个元组作为一个名为" job"的变量传递。最终,我最终想了解一点,所以我一直在使用这样的代码:
(jobId,label,用户名)= job
但是,我意识到这是维护方面的噩梦,因为现在,在不破坏所有现有代码的情况下,我永远无法在结果集中添加新字段。我应该怎么写呢?
这是我的两个最佳猜测:
(jobId,label,用户名)=(job [0],job [1],job [2])
...但是当我们有15 ... 20个字段时,缩放效果不佳
或者直接将SQL查询的结果转换为字典并传递给字典(我无法控制它作为元组开始的事实,这对我来说是固定的)
解决方案
回答
我想说字典绝对是最好的方法。它易于扩展,允许我们为每个值赋予一个合理的名称,并且Python具有许多内置的语言功能供使用和操作字典。如果以后需要添加更多字段,则只需更改将元组转换为字典的代码以及实际使用新值的代码即可。
例如:
job={} job['jobid'], job['label'], job['username']=<querycode>
回答
对于元组,添加或者更改字段总是很麻烦。没错,字典会更好。
如果我们想要使用稍微友好的语法的内容,则可能需要看一下有关一个简单的"类似于结构的"对象的问题的答案。这样,我们可以绕过一个对象,例如job
,并且比元组或者dict更容易访问其字段:
job.jobId, job.username = jobId, username
回答
也许这对于情况来说是矫kill过正,但是我很想创建一个"作业"类,该类将元组作为其构造函数参数,并具有各自的属性。然后,我将传递此类的实例。
回答
我会用字典。我们可以通过以下方式将元组转换为字典:
values = <querycode> keys = ["jobid", "label", "username"] job = dict([[keys[i], values [i]] for i in xrange(len(values ))])
这将首先创建一个数组[[" jobid",val1],[" label",val2],[" username",val3]],然后将其转换为字典。如果结果顺序或者计数发生变化,则只需更改键列表以匹配新结果。
PS本身在Python上仍然很新鲜,因此可能会有更好的方法来做到这一点。
回答
这个怎么样:
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一样。
回答
@Staale
有一个更好的方法:
job = dict(zip(keys, values))
回答
一个古老的问题,但是由于没有人提到,我将在Python Cookbook中添加它:
配方81252:使用元组进行灵活的查询结果访问
该配方是专门为处理数据库结果而设计的,并且元组解决方案允许我们按名称或者索引号访问结果。如问题所述,这避免了必须通过很难维护的下标访问所有内容。
回答
这是一个老问题,但是...
我建议在这种情况下使用命名元组:collections.namedtuple
这是特别有用的部分:
Subclassing is not useful for adding new, stored fields. Instead, simply create a new named tuple type from the _fields attribute.
回答
如果使用的是MySQLdb程序包,则可以将光标对象设置为返回dict而不是元组。
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