在 setdefault 之后附加到字典中的列表 [重复]

Posted

技术标签:

【中文标题】在 setdefault 之后附加到字典中的列表 [重复]【英文标题】:Append to list in a dictionary after setdefault [duplicate] 【发布时间】:2016-04-21 07:20:59 【问题描述】:

我有下面的代码,我试图在输入中每次出现时将 1 附加到元素的哈希值。

def test(Ar):
    hash_table = 
    for elem in Ar:
        if elem not in hash_table:
            hash_table.setdefault(elem,[]).append(1)
        else:
            hash_table[elem] = hash_table[elem].append(1)
    print(hash_table)

Ar = (1,2,3,4,5,1,2)
test(Ar)

输出:

1: None, 2: None, 3: [1], 4: [1], 5: [1]

预期输出:

1: [1,1], 2: [1,1], 3: [1], 4: [1], 5: [1]

我很困惑为什么 None 会进行追加。请解释发生了什么。

注意:

在输入 else 部分时,

hash_table[elem] = hash_table[elem].append(1) # the append() was not suggested at all by the IDE. I forcibly put it, hoping things will work.

【问题讨论】:

【参考方案1】:

list.append 是就地操作。所以它只是修改列表对象并且不返回任何东西。这就是为什么默认情况下,None 会从list.append 返回,而您将与此行中的键对应的值存储起来

hash_table[elem] = hash_table[elem].append(1)

在您的情况下,您根本不需要 if 条件。

def test(Ar):
    hash_table = 
    for elem in Ar:
        hash_table.setdefault(elem, []).append(1)
    print(hash_table)

因为,setdefault 会先在其中查找键 elem 并找到一些东西,然后它会返回对应的值。如果没有,它将创建键 elem 并使用传递给它的第二个参数作为值,然后返回值。


不用这个,你可以用collections.defaultdict,像这样

from collections import defaultdict
def test(Ar):
    hash_table = defaultdict(list)
    for elem in Ar:
        hash_table[elem].append(1)
    print(hash_table)

这与setdefault 版本的作用几乎相同


您似乎正在尝试查找元素的频率。在这种情况下,您可以简单地使用collections.Counter

from collections import Counter
Ar = (1, 2, 3, 4, 5, 1, 2)
print Counter(Ar)
# Counter(1: 2, 2: 2, 3: 1, 4: 1, 5: 1)

这将给出每个元素在传递的迭代中出现的次数。

【讨论】:

还要注意defaultdict 有一个default_factory 属性,当设置为None 时,默认dict 再次表现得像一个普通的dict。这对于想要使用 defaultdict 行为构造字典但又想要返回行为类似于常规字典的函数特别有用。【参考方案2】:

错误在这一行:

hash_table[elem] = hash_table[elem].append(1)

list.append(x) 返回None,您将其分配给hash_table[elem]

else 部分是不必要的,但仍要获得正确的结果,请删除 else 部分中的分配。


请注意,None 仅适用于出现两次的元素。如果任何元素存在三次,你就会得到一个错误。

【讨论】:

以上是关于在 setdefault 之后附加到字典中的列表 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

将值附加到字典中的一个列表 将值附加到字典中的所有列表

将字典附加到循环中的列表

使用 setdefault 重构 Python 字典列表

列表转换为字典(setdefault())

如何从列表中的多个字典附加到具有“内部”字典特定部分的另一个列表?

如何将字符串附加到字典中的列表