Re: [Python-Dev] syntactic shortcut - unpack to variably sized list

David Wilson wrote:
I dislike the use of 'popslice' as it implies somewhere along the lines the use of the slice type, which isn't happening.
If I was writing it, using a slice object as an argument to PySequence_GetItem is *exactly* the method I would be using to implement it: indices = PySlice_New(start, end, step); x = PySequence_GetItem(L, indices); PySequence_DelItem(L, indices); return x; Add reference counting, error checking and actually hook this up to the list type in the interpreter, and you're basically done. Heck, it could be argued that list.pop should just accept slices for the argument: a, b = L.pop(slice(2)) # Pop the first two items x, y, z = L.pop(slice(1:6:2)) # Pop items 1, 3 & 5 No new method required in that case - if you provide an index to list.pop, it will return a single item, if you provide a slice object, it will return a list. (Similar to the way list.__getitem__ currently works)
Also, what if at some future date it is decided that all magical syntax should be exposed using friendly method names too? Then you might have a list.slice which work in a much different way.[1]
List slicing is already exposed in Python in a few ways: L[:2] L.__getitem__(slice(2)) operator.itemgetter(slice(2))(L) Adding yet another way to spell it doesn't seem too likely. Given that lists *had* a __getslice__ method, and it has since been deprecated in favour of slice() objects, I'd be especially surprised to see list.slice (or equivalent) making a comeback. I will note that I only looked into the history of slicing this evening (when checking the C API for the sample implementation above). Having done so, the trend seems to have been away from having special methods for handling slices (__getslice__, __setslice__, __delslice__), and towards methods which can handle either a numeric index or a slice object (__getitem__, __setitem__, __delitem__). So maybe "list.pop(slice(2))" is the way to go (a non-optimised version could be written fairly easily using the existing internal list functions to retrieve and then delete the data. The main trick would be to leave the standard path through listpop alone to avoid any performance hit to the current users of list.pop() and list.pop(x)).
Second of all, you cannot have a non-default argument follow a default argument, so your proposed syntax would not work without breaking standard semantics and writing special code to act differently depending on the argument list length, and also take into account if keyword args are used, etc, etc.
The signature I proposed is identical to the existing signatures for the builtins range(), xrange() and slice(). It's true that normal Python functions and methods can't have a signature like that (it's a syntax error). C extensions (including the CPython interpreter) can do whatever they want, though. In this case, I think being consistent with slice() is more important than being consistent with normal function signatures. However, the suggestion above (allowing slice objects as arguments to list.pop) takes advantage of the existing slice() builtin, so none of that non-standard argument handling would need to be duplicated.
For an extra method, +1, but with a different name (I was thinking 'popitems', but dict.popitem returns a (k, v)).
What do you think of allowing slice objects to be used with list.pop()?
Oh one last thought. If "*<identifier>" were to be added, then what of "**<identifier>"? I can't think of any use for it, and so the whole scheme might appear confusing to beginners who find they can use ** in function declarations, but not in expressions.
Aye, I don't think it's an accident that "a, b *c = L" has been knocked on the head 3 times now. My main gripe with it is that it requires new syntax, yet still only supports a small subset of slicing. My idea about enhancing list.pop or adding a new method to list to provide the desired functionality is aimed at avoiding having the discussion *again* in the future (since clearly this is functionality some portion of the user community would make use of). I don't actually need the functionality myself, so I doubt I'll get around to providing a sample implementation. But the suggestion is there if any of the people that *do* want the feature would like to implement it.
[1] Exposing magical syntax (eg. indexers) as real methods is the Microsoft way for .NET (or at least, according to a C# book I read). It proves useful in occasions where interoperability with lesser systems is required, for example, a language that does not support custom indexers, or for enabling clients of an object bridge [that does not support cust..] to make full use of your classes.
Python already exposes most things as methods - I found browsing through the Language Reference a few months back extremely enlightening in that regard (specifically Section 3.3 Special Method Names). Cheers, Nick. -- Nick Coghlan | Brisbane, Australia Email: ncoghlan@email.com | Mobile: +61 409 573 268
participants (1)
-
Nick Coghlan