5

通常、X がスカラー、リスト、または dict のいずれかである型 X の引数を受け取り、他の情報に基づいて、同じキー値を持つ X のリストを返す関数が必要です。

def foo(info, k):
   return [bar(item,k) for item in processInfo(info)]

def bar(item, keydata):
   # pseudocode follows.
   # What we want to do is return an output of parallel type to the input key k,
   # using the key data to lookup information from the input item.
   if keydata is a scalar:
      return item[keydata]
   elif keydata is a list:
      return [item[k] for k in keydata]
   elif keydata is a dict:
      return dict((k,item[v]) for (k,v) in keydata.iteritems())
   else:
      raise ValueError('bar expects a scalar, list, or dict')

私の質問は、3 つのタイプの間でどのように発送できますか?


編集: 文字列は、リスト/反復可能ではなく、スカラーとして解釈されます。タプルは反復可能として解釈されます。

編集2:厳密なタイピングではなく、ダックタイピングが必要です。

4

7 に答える 7

5

stranddict型は反復可能であるため、適切な順序で処理を行う必要があります。

from collections import Iterable, Mapping  # in Python 3 use from collections.abc

def bar(item, keydata):
    if isinstance(keydata, Mapping):
        return {k: item[v] for (k,v) in keydata.iteritems()}
    elif isinstance(keydata, Iterable) and not isinstance(keydata, str):
        return [item[k] for k in keydata]
    return item[keydata]
于 2013-04-24T21:29:59.447 に答える
3

それは、入力をどの程度厳密にしたいかによって異なります。このisinstanceアプローチでは、受け入れる型を指定する必要があります (つまり、ダックタイピングはありません)。ユーザーがそれらのクラスまたはそれらのクラスのサブタイプのみを渡している限り、機能します。サポートするメソッドによってパラメータを区別することもできます。これの例は次のようになります

編集:文字列の特殊なケースを追加

if isinstance(keydata, basestring):
    # special case to avoid considering strings as containers
    # for python 3.x use str instead of basestring
    return item[keydata]
try:
    return dict((k,item[v]) for (k,v) in keydata.iteritems())
except AttributeError:
    # it's not a dict-like
    pass
try:
    return [item[k] for k in keydata]
except TypeError:
    # it's not iterable
return item[keydata]

制御フローの選択は、どの程度柔軟になりたいか、またあいまいなケースをどのように処理したいかによって異なります。たとえば、文字列は一連の文字またはスカラーと見なされますか?

于 2013-04-24T21:03:45.677 に答える
2

新しいファンシーなものを使用してください:)コレクションをインポートすることで

>>> isinstance([], collections.Sequence)
True
>>> isinstance({}, collections.Mapping)
True

typesモジュールも検討する必要があります

于 2013-04-24T20:57:58.243 に答える
0

すべての情報をありがとう!

keydata情報を反復処理する前に、前処理を行う必要があったため、これを行うことになりました。

def asKVlists(keydata):
    # return a tuple (keys, values, isScalar)
    # where keys and values are iterable
    if not isinstance(keydata, basestring):
        # check for dict behavior:
        try:
            return zip(*keydata.iteritems()) + [False]
        except AttributeError:
            pass

        # otherwise check for list behavior
        # make sure we can iterate over it
        try:
            iter(keydata)
            return (None, keydata, False)
        except TypeError:
            pass
    return (None, (keydata,), True)
于 2013-04-24T21:59:25.210 に答える
0

または、タイプを使用できますが、 http: //docs.python.org/2/library/functions.html#type によると isinstance が推奨されます

if type(asd) in (int, str):
    print 'asd is int or str'
于 2013-04-24T21:05:35.230 に答える