On Wed, Mar 08, 2017 at 08:29:19PM -0800, Alex Kleider wrote: > Things like this can usually be broken down into their component parts > but I've been unsuccessful doing so: > > def f(lst): > res = {} > for item in lst: > method_res = res.setdefault(item, []) > res.method_res.append(item) > # res.setdefault(item,[]).append(item) > return list(res.values()) > res.method_res.append(item) > > AttributeError: 'dict' object has no attribute 'method_res' > > Python must be doing some trickery behind the scenes.
Why do you say that? I'm not sure what result you expected, or what you are trying to do, but you have: res # a dict res.method_res No surprises that this fails with AttributeError. Dicts do not have an attribute or method called "method_res". Perhaps you meant to write: # not this # res.method_res.append( ... ) # this instead method_res.append( ... ) although part of the confusion is that "method_res" is a poorly chosen name. It isn't a method, it is a list. Perhaps it will help if I demonstrate what is going on with setdefault: py> mydict = {} py> alist = mydict.setdefault(1, []) py> alist [] py> mydict {1: []} So when you call setdefault on a dict, if the key is missing, it does two things: - it sets the key to the given default value; - and then it returns that same value. We could write our own setdefault method like this: def setdefault(self, key, default): if key in self: # self is the dictionary itself return self[key] else: self[key] = default return default Notice that default is used twice: it is the *same object*, not a fresh copy. py> id(alist), id(mydict[1]) (3080262860, 3080262860) So if default is a mutable list, changes to that list will show up in two places: py> alist.append(99) py> mydict {1: [99]} -- Steve _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor