On Mon, Dec 12, 2011 at 4:40 PM, Eelco <hoogendoorn.ee...@gmail.com> wrote: >> For a linked list, no *target and no copying is needed: >> >> head, tail = llist > > I have no idea what this means.
Each node of a linked list consists of a data member and a "next" member, that holds the next node in the list. The natural container for this and the way it is usually implemented in Python is a 2-element tuple. For example: llist = ('one', ('two', ('three', ('four', None)))) would be a linked list as typically constructed in Python, and it can be used in pretty much the same way that lists are used in Lisp. The result of the operation: head, tail = llist is: head = 'one' tail = ('two', ('three', ('four', None))) and as Terry pointed out, no copying is required to do this. I believe deque is also implemented as a doubly-linked list, which is probably why you keep referring to it as such, but that is an implementation detail. When you say "linked list" in relation to Python, the preceding is what comes to mind. >> >>>> head, deque(tail) = somedeque >> >> > Is better in every way I can think of (readability, consistence, >> > performance) than: >> >>>> head, *tail = somedeque >> >>>> tail = deque(tail) >> >> But your suggestion is much worse in each way than >> >> head = somedeque.popleft() > > No its not. First of all, its not semantically equivalent; popleft > mutates a collection type, and collection unpacking does not; it > creates a set of disjoint views of the collection's data. Whether its > worse in terms of readability is debatable, but in terms of the other > two stated metrics, your claim of it being any kind of worse is > objectively false. I definitely disagree on readability. Skimming this thread as I have been, it took me a while to get that your proposed syntax would create a second deque sharing internal state with the original, rather than creating a simple copy of the deque, which is what it looks like it should do. Incidentally, while that change is not really central to your syntax proposal, I think it would be very messy. For example, how do you propose keeping the length elements in sync? Inserting an item in one may or may not affect the length of the other. If I append an item to the end of one deque, should the other automatically be extended as well? What if the tail node of the second deque occurs after the tail node of the deque being appended? Does the appended element then get inserted into the middle of the second deque (I think it would have to be)? If I insert an element into the longer (second) deque that just happens to be immediately after the tail of the shorter deque, does *that* cause the shorter deque to be automatically extended? And likewise for operations at the head of the deque. None of these questions have obvious answers as to the "right" way to it, and for that reason I think this is probably best left to the user to implement a custom deque view class with whatever semantics they prefer. > Furthermore, this brings us back again to the point I raised several > times before. Yes, obviously you can already DO these things, but NOT > within the same uniform collection unpacking syntactic construct. > Again, you have failed to point out what is wrong with supplying a > type constrain to python and let it do the right thing based on that; > to reiterate: > > head, tail::deque = deque Python users generally follow the rule "explicit is better than implicit". Setting a general constraint and letting the language "do the right thing" is a kind of black magic that feels off because it tends to break that rule. But that's not to say that black magic never wins -- just look at super() and the MRO. > If you dont like the extra characters you have to type; there is of > course such a thing as defaults. You can choose: > head, tail:: = deque; if the type constraint is omitted, we could make > tail a list by default, or my preferred solution, infer it from the > right hand side type. I prefer the former. If it always creates a list by default, then the programmer reading this code three years later knows exactly what the type of tail is. If it instead infers it from the sequence being unpacked, then the programmer is forced to infer it as well, and it won't necessarily be obvious or even consistent. Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list