在 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 之后附加到字典中的列表 [重复]的主要内容,如果未能解决你的问题,请参考以下文章