69

I have a set like (669256.02, 6117662.09, 669258.61, 6117664.39, 669258.05, 6117665.08) which I need to iterate over, like

    for x,y in (669256.02, 6117662.09, 669258.61, 6117664.39, 669258.05, 6117665.08)
        print (x,y)

which would print

    669256.02 6117662.09
    669258.61 6117664.39
    669258.05 6117665.08

im on Python 3.3 btw

Zulu
  • 8,765
  • 9
  • 49
  • 56
Rasmus Damgaard Nielsen
  • 1,940
  • 4
  • 18
  • 33

3 Answers3

121

You can use an iterator:

>>> lis = (669256.02, 6117662.09, 669258.61, 6117664.39, 669258.05, 6117665.08)
>>> it = iter(lis)
>>> for x in it:
...     print (x, next(it))
...     
669256.02 6117662.09
669258.61 6117664.39
669258.05 6117665.08
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
37
>>> nums = (669256.02, 6117662.09, 669258.61, 6117664.39, 669258.05, 6117665.08)
>>> for x, y in zip(*[iter(nums)]*2):
        print(x, y)


669256.02 6117662.09
669258.61 6117664.39
669258.05 6117665.08
jamylak
  • 128,818
  • 30
  • 231
  • 230
  • 10
    Whoa. That's barely readable, consider it a hack. -1 for that. +1 for brevity, though. – Alfe May 28 '13 at 10:33
  • 11
    @Alfe read the official Python documentation **please**: http://docs.python.org/2/library/functions.html#zip ... especially the part that say *"This makes possible an idiom for clustering a data series into n-length groups using `zip(*[iter(s)]*n)`."* – jamylak May 28 '13 at 10:34
  • 24
    After reading such a documentation I would have stated the same thing about the documentation. Whenever a hack is assumed feasible enough, it is called an idiom. But that does not make it readable ;-) – Alfe May 28 '13 at 10:36
  • 4
    @Alfe alright then, I agree with you, the python documentation is obviously wrong we should not listen to it – jamylak May 28 '13 at 10:38
  • At least I'd propose to introduce a small function with a speaking name for performing such a task. Then that idiom can be understood. – Alfe May 28 '13 at 10:38
  • 2
    Don't be pissed so easily, jamylak ;-) It's nothing against you. But try to consider what the next developer will think if he or she stumbles across that kind of idiom. Do you really think it is easy to understand what it does unless you've read that documentation part? This reminds me strongly of the old C idiom `for (i=10; i-->0; ) { f(i); }` which is also nifty but barely understandable unless you already know it or invest extra time to understand what it does. – Alfe May 28 '13 at 10:41
  • @Alfe yes that code is completely fine, just like this one – jamylak May 28 '13 at 10:47
  • 4
    There obviously never is just one way of seeing it. – Alfe May 28 '13 at 10:56
  • 1
    @Alfe I don't know why you say it's not readable .. if you know how zip works it's so natural and smart way to do it – gioxc88 Oct 27 '19 at 21:44
  • I think it is way beyond the standard use of an iterator to use the same iterator in two places to take changing turns in where the elements it delivers pop up. I know it works and how but even now, some years after I last looked at this code, it took me some time to understand again what this code does. And I was warned by the context here. If these lines showed up in a piece of production code, I would guess first that this "innovative" use of an iterator was unintentional. It would raise a lot of questions which is _not_ a good thing in terms of maintainability. – Alfe Oct 28 '19 at 07:14
  • 1
    If your list has an odd number of items, the last item won't be processed. – Boris Verkhovskiy Oct 30 '19 at 00:05
  • 1
    I think, "readability" is subjective, let's not try to generalize it too much. To me, this is more readable than the accepted answer. Because no one is shifting an iterator in a sneaky way. +1 from me. – Zobayer Hasan Feb 26 '21 at 10:31
  • i also find this easier to read and it doesn't change the iterator in the middle of the loop. maybe in the intervening years zip has become more common so more readable? – keithpjolley Aug 05 '22 at 16:20
  • @keithpjolley In terms of readability I'd just use `chunked` from `more_itertools` package https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked but I guess I also wouldn't be against using `zip` directly too, imo it's readable – jamylak Aug 07 '22 at 23:48
14

The grouper example in the itertools recipes section should help you here: http://docs.python.org/library/itertools.html#itertools-recipes

from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

You would then it use like this:

for x, y in grouper(my_set, 2, 0.0):  # Use 0.0 to pad with a float
    print(x, y)
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Lllama
  • 374
  • 1
  • 9