On 28/11/2017 23:15, Alon Snir wrote: > On Wed, Nov 29, 2017 at 5:46 AM, Alon Snir <alons...@hotmail.com> wrote: >> I would like to mention that the issue of assignment to a target list, is >> also relevant to the case of elementwise assignment to a mutable sequence >> (e.g. lists and arrays). Here as well, the rhs of the assignment statement >> states the number of elements to be assigned. Consequently, the following >> example will get into infinite loop: >> >>>>> from itertools import count >>>>> A = [] >>>>> A[:] = count() >> >> Writing "A[:2] = count()" will cause the same result. >> Here as well, it is currently safer to use islice if the rhs is a generator >> or an iterator. e.g.: >> >>>>> it = count() >>>>> A[:] = islice(it,2) >> >> In my opinion, it is be better to devise a solution that could be applied in >> both cases. Maybe a new kind of assignment operator that will be dedicated >> to this kind of assignment. i.e. elementwise assignment with restriction on >> the number of elements to be assigned, based on the length of the lhs object >> (or the number of targets in the target list). >> > > ChrisA wrote: > Hmm. The trouble is that slice assignment doesn't have a fixed number of > targets. If you say "x, y = spam", there's a clear indication that 'spam' > needs to provide exactly two values; but "A[:] = spam" could have any number > of values, and it'll expand or shrink the list accordingly. > > Rhodri James wrote: > Flatly, no. It is better not to ask for things you don't want in the first > place, in this case the infinite sequence. > Still, don't let me discourage you from working on this. If you can define > how such an assignment would work, or even the length of A[:] as an > assignment target, I'm not going to dismiss it out of hand. > > > My answer: > > The idea is to define an alternative assignment rule, that is to assign > exactly as many elements as the current length of the lhs object (without > expanding or shrinking it). Suppose "?=" is the operator for the alternative > assignment rule; A=[None]*2; and "iterator" is any iterator (finite or > infinite). In this case, the following code: > >>>> A ?= iterator > > would behave like this: > >>>> A[:] = islice(iterator, 2) # where 2 is the length of A > > And as suggested earlier for the case of assignment to a target list, the > following code: > >>>> x, y ?= iterator > > would behave like this: > >>>> x, y = islice(iterator, 2) # where 2 is the number of targets > > Regarding the length issue: > Is there any difficulty in finding the length of a sliced sequence? After > all, the range object has a len method. Therefore, the length of A[s] (where > s is a slice object) could be evaluated as follows: > >>>> len(range(*s.indices(len(A))))
Just a thought but what about a syntax something along the lines of: a, b, *remainder = iterable Where remainder becomes the iterable with the first two values consumed by assigning to a & b. If the iterator has less than 2 values, (in the above case), remaining it should error, if it has exactly 2 then remainder would become an exhausted iterable. Of course the user could also use: a, b, *iterable = iterable Others may differ but this syntax has a lot of similarity to the f(a, b, *args) syntax, possibly enough that most users could understand it. -- Steve (Gadget) Barnes Any opinions in this message are my personal opinions and do not reflect those of my employer. --- This email has been checked for viruses by AVG. http://www.avg.com _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/