2

在此示例中,我从一组中获取字母并将它们附加到字典中,其中字母成为键,文字 1 成为每对的值。

def base_dict_from_set(s):
    return reduce(lambda d,e : addvalue(1, e, d), s, dict())


def addvalue(value, key, d):
    d[key] = value
    return d
>>> base_dict_from_set(set("Hello World!".lower()))
{'o': 1, '!': 1, 'l': 1, 'd': 1, 'w': 1, ' ': 1, 'r': 1, 'e': 1, 'h': 1}

我想知道我是否可以以某种方式摆脱“addvalue”辅助函数并添加元素并在 lambda 函数本身中引用修改后的字典。

addvalue 本身的例程对我来说非常简单,所以我更喜欢看起来像这样的东西:

def base_dict_from_set(s):
    reutrn reduce(lambda d,e : d[e] = 1, s, dict())

我在 python 方面没有很多经验,我来自函数式编程的角度。我的目标是了解 python 的功能,但我太缺乏经验,无法正确表达和谷歌搜索我正在寻找的内容。

4

6 回答 6

4

您要做的是为什么dict.fromkeys存在:创建一个将每个键映射到相同常量值的字典。

>>> dict.fromkeys("Hello World!".lower(), 1)
{'h': 1, 'e': 1, 'l': 1, 'o': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1, '!': 1}

无需将字符串转换为set第一个字符串,因为任何重复项都将被以下事件覆盖。

(如果常量值是可变的,您应该使用 dict 推导来确保每个键都有自己的可变值,而不是每个键共享对相同可变值的引用。)

于 2021-09-10T12:44:17.950 回答
3

addvalue要准确回答所提出的问题,是的,您可以通过替换addvalue(1, e, d)来摆脱{**d, e:1}.

尽管如此,您的代码仍然有问题。它不计算出现次数,而是key: 1为字符串中的每个字母创建一个字典,它应该创建一个字典key: number_of_occurences来实现这一点,你应该替换addvalue(1, e, d){**d, e: 1 + (d[e] if e in d else 0)}不是转换字符串,set因为它消除了重复

于 2021-09-10T12:43:20.477 回答
3

您可以对相同的结果使用dict 理解:

{l: 1 for l in set("Hello World!".lower())}
于 2021-09-10T12:38:25.380 回答
2

当您的目标是将输入集合reduce中的每个项目(字符串中的字母)转换为输出集合(键/值对,其中键是字母而值是一个常数),彼此独立。

在我看来,reduce当需要对序列中的项目进行操作并考虑所有先前的项目时(例如,在计算值的总和时)。

因此,在我看来,在功能风格中,使用maphere 会比 更合适。reducePython 支持这一点:

def quant_dict_from_set(s):
    return dict(map(lambda c: (c, 1), s.lower()))

Wheremap将字符串转换为键/值对,dict构造函数将这些对收集到字典中,同时消除重复键。

但更惯用的方法是使用字典理解dict.fromkeys构造函数

于 2021-09-10T12:49:15.053 回答
1

哈克且难以阅读,但最接近lambda您尝试编写的内容,并且希望具有教育意义:

>>> f = lambda d, e: d.__setitem__(e, 1) or d
>>> d = {}
>>> output = f(d, 42)
>>> output
{42: 1}
>>> output is d
True

使用__setitem__避免了=分配。

__setitem__返回None,因此表达式的d.__setitem__(e, 1) or d计算结果始终为d,由 . 返回lambda

于 2021-09-10T12:46:51.340 回答
0

您可以使用专门用于计算元素出现次数的collections.Counter子类。dict

>>> import collections

>>> collections.Counter('Hello, World!'.lower())
Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ',': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1, '!': 1})

>>> collections.Counter(set('Hello, World!'.lower()))
Counter({'w': 1, 'l': 1, 'r': 1, ',': 1, 'h': 1, 'd': 1, 'o': 1, 'e': 1, ' ': 1, '!': 1})

请注意,Counter如果您想对元素进行计数,或者如果您想将值初始化为常量 1,这是合适的。如果您想将值初始化为另一个常量,那么 Counter 将不是解决方案,您应该使用字典理解dict.fromkeys构造函数

于 2021-09-10T12:37:49.160 回答