0

dict次のようなa のすべての非整数キーにアクセスする必要があります。

result = { 
           0 : "value 1",
           1 : "value 2",
           "key 1" : "value 1",
           "key 2" : "value 2", 
         }

私は現在これを行っています:

headers = [header for header in tmp_dict.keys() if not isinstance(header, int)]

私の質問:

  1. タイプチェックなしでこれを行う方法はありますか?
  2. これは、属性を使用しtmp_dictたクエリから出てきたもので、何らかの理由でデータを含むすべての列名を期待どおりに返しますが、整数でインデックス付けされた同じデータも含まれています。列の値とデータのみを含む辞書としてクエリ結果を取得するにはどうすればよいですか?pymssqlas_dict=True

ご協力いただきありがとうございます!

PS - 2に答える可能性があることで問題が解決されたにもかかわらず、型チェックなしでこれを行う方法に興味があります。主に、「型チェックは絶対にしない」と言う人向けです。

4

4 に答える 4

1

背後にある理論的根拠as_dict=Trueは、インデックスと名前でアクセスできることです。通常は atupleにインデックスを付けますが、互換性の理由から、dictあたかもtuple列番号に依存するコードが、列名が使用可能であることを意識せずに動作できることを意味するかのように a にインデックスを付けることができます。

(名前またはインデックスのいずれかで) 列を取得するためだけに使用している場合result、それらを削除することを心配する理由がわかりません。関係なく続けてください。(何らかの理由でデータをピクルするか、別の場所で永続化する予定がない限り...)

ただし、それらを除外する最善の方法は、使用することですisinstance-この場合のダックタイピングは、実際には非Pythonicで非効率的です。例えば:

names_only = dict( (k, v) for k,v in result.iteritems() if not isinstance(k, int) )

tryexceptダンスの代わりに。

于 2012-07-18T17:16:05.423 に答える
1

型チェックに関するあなたの質問に関しては、ダック型のアプローチは、int.

def can_be_int(obj):
    try:
        int(obj)
    except (TypeError, ValueError):
        return False
    return True

headers = [header for header in tmp_dict.keys() if not can_be_int(header)]

floats は切り捨てることで sに変換できるため、必ずしも完全に同等であるとは限りませintん。

上記のわずかなバリエーションは、のcoerce(0, obj)代わりに使用することですint(obj)。これにより、整数を持つ共通の型に変換できるあらゆる種類のオブジェクトが許可されます。0 + obj and 1 * obj整数を使用した数式で使用できるものをチェックするようなこともできます。

文字列表現がすべて数字かどうかを確認することもできます。

headers = [header for header in tmp_dict.keys() if not str(header).isdigit()]

これはおそらく型チェックを使用しないソリューションに近いですが、遅くなります。もちろん、列名が数字のみの文字列になる可能性は十分にあります。(正直に言うと、これらのアプローチの多くでは失敗します。)

明示的な型チェックが本当に最良の選択である場合もあります。そのため、言語には型をチェックできるツールがあります。この状況では、特に結果ディクショナリがキーとして整数と文字列のみを持つことが文書化されているため、問題ないと思います。isinstance()そして、明示的にチェックするのではなく、使用することで正しい方法でそれを行っていますtype() == int

于 2012-07-18T16:44:49.797 に答える
1

pymssql (1.0.2) のソース コードを見ると、モジュールが整数によってインデックス付けされたデータを生成しないというオプションがないことは明らかです。ただし、列名が空の場合、列名で索引付けされたデータは省略できることに注意してください。

/* mssqldbmodule.c */
PyObject *fetch_next_row_dict(_mssql_connection *conn, int raise) {
    [...]
    for (col = 1; col <= conn->num_columns; col++) {
        [...]
        // add key by column name, do not add if name == ''
        if (strlen(PyString_AS_STRING(name)) != 0)
            if ((PyDict_SetItem(dict, name, val)) == -1)
                return NULL;

        // add key by column number
        if ((PyDict_SetItem(dict, PyInt_FromLong(col-1), val)) == -1)
            return NULL;
    }
    [...]
}

最初の質問に関しては、型チェックによって結果セットをフィルタリングすることが、それを行うための最良の方法であることは間違いありません。これは、as_dict が False の場合に pymssql がデータを返す方法とまったく同じです。

if self.as_dict:
    row = iter(self._source).next()
    self._rownumber += 1
    return row
else:
    row = iter(self._source).next()
    self._rownumber += 1
    return tuple([row[r] for r in sorted(row.keys()) if type(r) == int])
于 2012-07-18T16:35:33.233 に答える
0
>>> sorted(result)[len(result)/2:]
['key 1', 'key 2']

これにより、重複したinteger-keyedエントリが削除されます。でも、あなたがやっていることは大丈夫だと思います。

于 2012-07-18T16:36:36.447 に答える