Append to list in a dictionary after setdefault
Solution 1
The list.append
is an in-place operation. So it just modifies the list object and doesn't return anything. That is why, by default, None
is getting returned from list.append
and you are storing that corresponding to the key in this line
hash_table[elem] = hash_table[elem].append(1)
In your case, you don't need the if
condition at all.
def test(Ar):
hash_table = {}
for elem in Ar:
hash_table.setdefault(elem, []).append(1)
print(hash_table)
because, setdefault
will first look for the key elem
in it and it found something, then it will return the value corresponding to it. And if it doesn't then it will create key elem
and use the second argument passed to it as the value and then return then value.
Instead of using this, you can use collections.defaultdict
, like this
from collections import defaultdict
def test(Ar):
hash_table = defaultdict(list)
for elem in Ar:
hash_table[elem].append(1)
print(hash_table)
This would do almost the same thing as the setdefault
version
It looks like you are trying to find the frequency of elements. In that case you can simply use 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})
This will give the number of times each and every element occurred in the iterable passed.
Solution 2
The bug is in this line:
hash_table[elem] = hash_table[elem].append(1)
list.append(x)
returns None
, which you are assigning to hash_table[elem]
The else
part is unnecessary, but still for getting correct results, remove the assignment in the else
part.
Note that the None
is only for elements that occur twice. If any element existed thrice, you'd have gotten an error.
KurinchiMalar
Updated on June 11, 2022Comments
-
KurinchiMalar almost 2 years
I have the below code where I am trying to append a 1 to the hash of an element, on every occurence of it in input.
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)
Output:
{1: None, 2: None, 3: [1], 4: [1], 5: [1]}
Expected Output:
{1: [1,1], 2: [1,1], 3: [1], 4: [1], 5: [1]}
I am puzzled why None gets in on doing an append. Kindly explain what is happening.
Note:
On typing the else portion,
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.
-
mgilson over 8 yearsAlso note that
defaultdict
have adefault_factory
property, which when set toNone
makes the default dict behave like a regular dict once again. This is particularly useful for functions which want to construct a dictionary using defaultdict behaviors, but then want to return something that behaves like a regular dict.