Home > Enterprise >  Why appending is returning None
Why appending is returning None

Time:10-24

I'm trying to swap keys and values, and append the keys if the values are duplicated. But When trying to append the result is None.

def swap_keys_and_values(d):
    new_d = {}
    for k, v in d.items():
        if new_d.get(v):
            print(new_d.get(v), k)
            print(new_d.get(v).append(k))
            new_d[v] = new_d.get(v)
            new_d[v] = list(k) 
    return new_d
    
    print(swap_keys_and_values({'a': 1, 'b': 2, 'c': 1}))

['a'] c
None
{1: ['c'], 2: ['b']}

CodePudding user response:

.append() is an in-place operation, it modifies the object it is called on.

Some in-place operations will return the object itself (and this is desirable for allowing method-chaining), but the basic list methods of Python do not have this behaviour (favouring speed and minimalism over usability for programmers).

All functions (and thus methods) return some result, but if no specific result is returned, the return value is None, which is the case here.

Note that having an in-place method can be confusing to a developer - they may assume that because the function is returning a modified value, the original was left unmodified and they have been provided with a copy of it. This is a conflict of two programming styles - neither is technically wrong, but mixing them can lead to very confusing code.

For example:

xs = [1, 2, 3]
ys = xs.returning_append(0).sort()

Here, a 0 is appended to the list [1, 2, 3], but does xs change? And does sort() also return a value and is the value of ys now [0, 1, 2, 3] or None?

Python favours:

xs = [1, 2, 3]
xs.append(0)
xs.sort()

And if you don't want xs to change:

xs = [1, 2, 3]
ys = xs.copy()
ys.append(0)
ys.sort()

CodePudding user response:

append() is a list method, not a dict method. You need to make sure you have a list first, and then set that list into the dictionary.

If you intend for each value in the new dict to be a list of all the previous keys that had that value, then you should use:

values = new_d.get(v, [])
values.append(k)
new_d[v] = values   # required, as getting a list by default from .get() won't set the value for that key to the empty list.

If you use new_d = defaultdict(list) with defaultdict from the collections library, you could condense these 3 lines to the single line of new_d[v].append(k)

  • Related