On Sun, Dec 2, 2018 at 2:23 AM Chris Angelico <ros...@gmail.com> wrote:
> On Sun, Dec 2, 2018 at 11:55 AM Morten W. Petersen <morp...@gmail.com> > wrote: > > > > On Sat, Dec 1, 2018 at 1:11 AM Chris Angelico <ros...@gmail.com> wrote: > >> > >> On Sat, Dec 1, 2018 at 10:55 AM Morten W. Petersen <morp...@gmail.com> > wrote: > >> > But this raises the question of how to write Python code, > >> > short and sweet, that could handle infinite iterators in > >> > such an unpack with multiple variables to assign to. > >> > > >> > Which I guess is mostly theoretical, as there are other > >> > ways of designing code to avoid needing to unpack > >> > an infinite iterator using the * prefix. > >> > >> It could only be done with the cooperation of the iterable in > >> question. For instance, a range object could implement a "remove > >> first" operation that does this, and several itertools types wouldn't > >> need to change at all. But it can't be done generically other than the > >> way it now is (pump the iterator the rest of the way). > > > > I wasn't able to follow this, could you elaborate? > > > > The way *x works in unpacking is that the entire iterable gets > unpacked, and everything gets put into a list that is then assigned to > x. This is generic, works on any iterable, but doesn't take advantage > of anything. Consider: > > >>> x = range(3, 20, 5) > >>> first, *rest = x > >>> first > 3 > >>> rest > [8, 13, 18] > > If a range object were asked to yield its first-and-rest in this way, > it could instead return range(8, 20, 5) - add the step onto the start, > job done. Same if you ask for some off the beginning and some off the > end And with a number of the itertools iterables/iterators, the "rest" > wouldn't actually need to change anything, since the iterator will get > consumed. This would need explicit support from the iterable, though, > as Python can't know how to do this generically; so there would need > to be a protocol for "unpack". > Aha, yes - I see. While we're on the subject, I did a test in my Python interpreter: Python 3.6.7 (default, Oct 22 2018, 11:32:17) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> range(0,3,100) range(0, 3, 100) >>> len(range(0,3,100)) 1 >>> range(0,100) range(0, 100) >>> len(range(0,100)) 100 >>> Where a range with a step, gives the length 1, while a plain range gives the right length. I think that's confusing and inconsistent, and it would be nice to have some "value to be calculated" for the length integer as well. -Morten -- Videos at https://www.youtube.com/user/TheBlogologue Twittering at http://twitter.com/blogologue Blogging at http://blogologue.com Playing music at https://soundcloud.com/morten-w-petersen Also playing music and podcasting here: http://www.mixcloud.com/morten-w-petersen/ On Google+ here https://plus.google.com/107781930037068750156 On Instagram at https://instagram.com/morphexx/ -- https://mail.python.org/mailman/listinfo/python-list