2008-09-03 3 views
12

私は、SQLクエリからの行であるタプルを返すPythonコードのメソッドを持っています。Pythonでタプルを分割する - ベストプラクティスですか?

私は関数の間を簡単に渡すために、タプル全体を 'job'という変数として渡してきました。これは3つのフィールドから構成されています(jobId、label、username)。しかし、最終的には少し分かりたいので、私はこのようなコードを使っています: (jobId、label、username)= job

これはメンテナンスの悪夢ですが、なぜなら、既存のコードをすべて破ることなく、結果セットに新しいフィールドを追加することはできないからです。これをどう書かなければならないのですか? (JOBID、ラベル、ユーザー名)=(ジョブ[0]、仕事[1]、仕事[2]) ...しかし、あなたが持っているときにはうまくスケールしない:ここでは

は私の2つの最高の推測があります15 ... 20フィールド

またはSQLクエリの結果をすぐに辞書に変換して渡すことができます(タプルとしての生活を始めることはできません。 )

答えて

13

私は辞書が間違いなくそれを行う最良の方法だと言いたいと思います。これは簡単に拡張可能で、各値にわかりやすい名前を付けることができます。Pythonには辞書を使用したり操作したりするための多くの組み込み言語機能があります。後でフィールドを追加する必要がある場合は、タプルを辞書に変換するコードと実際に新しい値を使用するコードを変更するだけです。例えば

:常にフィールドを追加または変更するには面倒になるタプルで

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

も参照してください。http://code.activestate.com/recipes/81252/ – Jay

0

。あなたは辞書がはるかに良くなることは間違いありません。

構文が少しわかりやすいものをお望みなら、単純な 'struct-like'オブジェクトについての回答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]、[ "ラベル"、VAL2]、[ "ユーザー名"、val3は]]を作成し、それを辞書に変換します。結果の順序または数が変更された場合は、新しい結果と一致するようにキーのリストを変更するだけです。

PSはまだPythonで新しくなっていますので、これを行うより良い方法があるかもしれません。

+2

ZipのAaron Maenpaaの回答を参照してください。 Pythonで一般的な初心者間違いは、zipで十分であるときにリスト内包を使用することです。 –

-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

これはまた非常に保守的なコードです、唯一の "問題"は辞書を扱うコードを再構築することです。 –

2

古い質問は、誰もがそれを言及していないので、私は、Pythonクックブックからこれを追加します:

Recipe 81252: Using dtuple for Flexible Query Result Access

このレシピは、データベースの結果を扱うために特別に設計されており、dtupleソリューションでは名前またはインデックス番号で結果にアクセスできます。これは、あなたの質問に記載されているように、維持管理が非常に難しい下付き文字ですべてにアクセスする必要がなくなります。

5

これは私がこのような状況で名前のタプルを使用してお勧めしたいの古い質問が...

です:collections.namedtuple

は、これは便利だろうと、特に、一部です:

サブクラス化は、新しい格納フィールドを追加するのには役に立ちません。代わりに、単に_fields属性から新しい名前付きタプル型を作成します。

+2

その他の利点:* namedtuple *アプローチは辞書より少ないメモリしか使用せず、値を更新するための\ _replace()メソッドをサポートしています。 –

+0

技術的には、 '_replace()'は、 'namedtuple'クラスのインスタンスが通常のタプルのように不変であるため、置き換えられた値を持つ新しいタプルを作成します。 – JAB

0

MySQLdbパッケージを使用している場合は、タプルの代わりにdictsを返すようにカーソルオブジェクトを設定できます。

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