将字典推导应用于defaultdict

3
我有以下代码,它会将一个openpyxl工作表中的三个列解析成一个defaultdict
def campaigns_and_adsets_and_pageviews_from_ga(ourTab):
    d = defaultdict(lambda: defaultdict(int))
    for row in ourTab.rows[1:-1]:
        if ('Facebook' in row[0].value) and ('(not set)' not in row[2].value):
            d[row[1].value][row[2].value] += row[4].value
    return d

其输出结果如下所示:
In [790]: campaigns_and_adsets_and_pageviews_from_ga(ourTab)
Out[790]: 
defaultdict(<function __main__.<lambda>>,
            {u'XXX 20160314': defaultdict(int,
                         {u'Carnival desktopfeed': 2.0,
                          u'Carnival mobilefeed': 588.0,
                          u'PYS Broad desktopfeed': 371.0,
                          u'PYS Broad mobilefeed': 1192.0}),
             u'YYY Intl 20150903': defaultdict(int,
                         {u'CA desktopfeed': 2.0}),

我想做的是将每个元素中的最终值(即2.0、588.0等)乘以一个常数,从而得到另一个defaultdict(甚至一个普通的嵌套dict也可以)。
能否通过某种方式将defaultdict解构为嵌套字典,以便允许进行转换?或者还有哪些其他方法可行?

4
你忘记调用函数了。 - Alex Hall
4
你需要使用.items()以便能够遍历每个条目。 - g.d.d.c
2
鉴于立即发现了两个错误,我建议您首先草率/模拟您的campaigns_and_adsets_and_pageviews_from_ga函数,只返回定义嵌套字典的字典文字(暂时不要管defaultdict):return {u'XXX 20160314': {u'Carnival desktopfeed':2.0,...}}。然后编写正确复制并将数字加倍的代码。然后切换回使用计算结果返回defaultdict。这样您就不会分心,认为所有出现问题都必须与defaultdict有关 :-) - Steve Jessop
@SteveJessop 说得好,有道理。 - Pyderman
1个回答

4

您可以使用一个简单的递归函数,将数字与给定值相乘,并针对每个dict实例构建一个新的字典:

from numbers import Number

def multiply(o, mul):
    if isinstance(o, dict):
        return {k: multiply(v, mul) for k, v in o.items()}
    elif isinstance(o, Number):
        return o * mul
    else:
        return o

以您提供的示例defaultdict和乘数2为输入,输出结果如下:

{
    u'YYY Intl 20150903': {u'CA desktopfeed': 4.0}, 
    u'XXX 20160314': {
        u'Carnival desktopfeed': 4.0, 
        u'PYS Broad desktopfeed': 742.0, 
        u'PYS Broad mobilefeed': 2384.0, 
        u'Carnival mobilefeed': 1176.0
    }
}

请注意,该示例无法处理列表,您需要添加更多的代码。

1
现在那才是超越传统思维的创新。我之前不知道numbers模块,感谢你在这两个方面给我的帮助。 - Pyderman
@Pyderman:在我意识到需要有一种比分别处理“float”和“int”更简单的方法之后,我也不得不搜索它。 - niemmi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接