簡體   English   中英

編寫此篩選列表理解的最pythonic方法是什么?

[英]What's the most pythonic way to write this filtered list comprehension?

也許我太晚了。

我有一個對象是字典周圍的薄包裝器。 它會偽裝成字典中任何鍵的屬性,如果引用了不存在的鍵,則返回None。

我想只找回三個可能的鍵的唯一“truthy”值。 (不是沒有)。 對象可能沒有一個或多個鍵。 或者,它可以在兩個或三個鍵中具有相同的值。

這段代碼做我想要的:

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

我只是不喜歡兩次重復getattr()的樣子。 我覺得我忽略了一個明顯更好的方法來做到這一點。

您可以在之后過濾掉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])

如果您的瘦包裝器返回默認值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']))

另一個使用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)

正如您所看到的,只有一個循環,並且getattr()僅針對每個字段調用一次。 並且只有“truthy”值被添加​​到結果中。 我認為這比獲得所有結果更有效,然后在以后刪除“非真實”值。 但如果我錯了,請糾正我。 干杯。

就像是:

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')
# []

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM