Zip is just "pair each x with each y". Literally:
[1,2,3,4]
[5,6,7,8]
# go down each column, yielding these in order
[1,5]
[2,6]
[3,7]
[4,8]
And then you drop ones with no pair. So zipping [1] and [2,3] makes just [1,2]. The same is true if you reverse the arguments, so [1,2] and [3] => [1,3]
The example is sorta obtuse at a glance[1], but this: `zip(xs, xs[1:])` equates to this:
[1,2,3,4]
[2,3,4] # copy and drop the first element
# outputs columns
[1,2]
[2,3]
[3,4]
So it's a one-liner to make a list of of each consecutive pair of items in a list. All `zip(x, x[1:])` do the same thing regardless of the ultimate use of such a construct.
But yeah, I have seen some very confusing uses of zip before sitting and thinking for a bit. TBH I think much of it is just familiarity though - after seeing a million `for (i=0;i<thing.len();i++) { ... }` I can pattern-match and figure this out easily:
for (i=0, l=thing.len(); i<l-1; i++) {
list.push([thing[i], thing[i+1]])
}
(though `i<l-1` ease may depend on font) but similarly-common functional idioms just don't slide into position as easily. Yet.
[1]: I'm guessing it's the equivalent of finding the largest "gap" between a bunch of sizes of things.