2

多分私は遅すぎるだけです。

辞書の薄いラッパーであるオブジェクトがあります。ディクショナリ内の任意のキーのプロパティを持っているふりをし、存在しないキーが参照されている場合は None を返します。

3 つの可能なキーについて、一意の「真実の」値のみを取得したいと考えています。(なしではない)。オブジェクトは 1 つ以上のキーを持っていない可能性があります。または、2 つまたは 3 つのキーで同じ値を持つ場合もあります。

このコードは私が望むことを行います:

set(getattr(obj, field) for field in ['field1', 'field2', 'field3'] if getattr(obj, field))

getattr() を2回繰り返す見た目が気に入らないだけです。これを行うための明らかにより良い方法を見落としているように感じます。

4

4 に答える 4

4

None後で値を除外できます。

set(filter(bool, [getattr(obj, field) for field in ['field1', 'field2', 'field3']]))

または、オブジェクトを忘れることもできます。これはおそらく私がそれをする方法です:

a_dict = {'key1': 1, 'key2': 2, 'key3missing': 3}

print set([a_dict[key] for key in ['key1','key2','key3'] if key in a_dict])

# prints: set([1, 2])
于 2012-09-12T09:01:42.287 に答える
3

Thin ラッパーが default を返す場合None:

s = set(getattr(obj, field) for field in ['field1', 'field2', 'field3']) - {None}

別の可能性:

s = set(filter(None, (getattr(obj, field) for field in ['field1', 'field2', 'field3']))
于 2012-09-12T08:59:12.443 に答える
3

getattr のデフォルトを使用した別の方法:

set(x for x in getattr(obj, field, None) for field in ['field1', 'field2', 'field3'] if x)

編集:

ここでは、この関数の背後にあるロジックを示します。また、他のソリューションよりも優れていると思う理由を示します (間違っている可能性もありますが、人生は間違いから学ぶことがすべてです)。

obj = Your_Object
fields = ['field1', 'field2', 'field3']

def get_set(obj, fields):
    result = []
    for field in fields:
        x = getattr(obj, field, None)
        if x:
            result.append(x)
    return set(result)

ご覧のとおり、ループは 1 つgetattr()だけで、フィールドごとに 1 回だけ呼び出されます。そして、「真実の」値のみが結果に追加されます。これは、すべての結果を取得し、後で「真実ではない」値を削除するよりも少し効率的だと思います。しかし、私が間違っている場合は修正してください。乾杯。

于 2012-09-12T09:42:58.707 に答える
1

何かのようなもの:

from operator import attrgetter

class DictWrapper(object):
    def __init__(self, d):
        self.d = d

    def __repr__(self):
        return repr(self.d)

    def __getattr__(self, name):
        return self.d.get(name)

    def truthy(self, *keys):
        values = attrgetter(*keys)(self)
        if not isinstance(values, tuple):
            values = (values,)
        return filter(None, set(values))

dw = DictWrapper({'x': 3, 'y': None, 'z': 'zebra'})
dw.truthy('x', 'y' ,'z', 'bob')
# [3, 'zebra']
dw.truthy('x')
# [3]
dw.truthy('y')
# []
于 2012-09-12T10:12:38.553 に答える