Nov. 23, 2020

Packaging loops with zip

Zip incrementally selects values from two or more iterables provided per cycle of a loop. The selected values are combined into a tuple which can be unpacked into multiple variables.


Page contents

Iterate simultaneously over multiple lists

A for loop operates more like foreach in Python. Iterating over elements from one iterable, like list is simple. What to do if elements are needed to be picked from two or more lists per cycle? This is where the zip method comes in. It allows multiple iterables to be looped over at the same time. For every cycle, zip picks one element from each of the iterables provided.

  • two independent iterables
  • zip simultaneous packages elements from each
  • stops when one iterable is expended

Py3: zip multiple lists

#   two lists
lsta = [1,2,3,4]
lstb = list('hello')

#   pair holds one value from each list
for pair in zip(lsta, lstb):
    print(pair)

#=  (1, 'h')
#   (2, 'e')
#   (3, 'l')
#   (4, 'l')

Notes: Using the zip explained

The zip method packages multiple iterables provided to it. They can be a mixed type of iterables. During each loop, zip queries the next value from each iterable. All the elements extracted are packaged into a single tuple. If a single variable is provided, the tuple is assigned to it. If multiple variables are present in the statement, then the tuple is unpacked and appropriately assigned to the variables. Check out tuple unpacking for more details. The iteration continues while each iterable is able to supply a value. When one is exhausted, the whole loop exits.

Mixed list of iterables

A mixed set of iterables like lists, tuples, dictionaries, range, or generators can all be provided to a single zip statement.

  • multiple iterables packaged into a container list
  • unpack values from zip into separate variables
  • stop at the end of shortest iterable

Py3: Mixed bag of iterables

itra = [1,2,3]
itrb = range(5,8)
itrc = 'iterate'

#   iterate with 3 iterables
#   unpack values into separate variables
for a,b,c in zip(itra,itrb,itrc):
    print(a,b,c)

#=  1 5 i
#   2 6 t
#   3 7 e    

Instead of providing each iterable individually, they can be packaged into a list.

Py3: Container of iterables

itra = (1,2,3,4)
txtb = 'abc'
rngc = range(10,14)

#   pack iterables as a list
container = [itra, txtb, rngc]
for a, b, c in zip(*container):
    print(a, c, b)

#=  1 10 a
#   2 11 b
#   3 12 c

Notes: Packaging iterables can be powerful

Multiple iterables can be packaged into a list and unpacked inside a zip statement. This is a very powerful feature, as complex sets of iterables can be created to be iterated together.

Shifted values from iterable

Often we need to get multiple values from the same iterable. Say a pair of values are needed per iteration.

  • multiple values from same iterable
  • shift is fixed and set at start

Py3: Pair of values

nums = [1,2,3,4,5]

#   offset second iterable
for pair in zip(nums, nums[1:]):
    print(pair)

#=  (1, 2)
#   (2, 3)
#   (3, 4)
#   (4, 5)

The pair of values example can be extended and generalized to extract triplets or multiple values from an iterable.

Py3: Recode pair to triplet

nums = [1,2,3,4,5]

#   create container of iterables
container = []
for s in range(3):
    container.append(nums[s:])

#   co-iterate contents
for triplet in zip(*container):
    print(triplet)

#=  (1, 2, 3)
#   (2, 3, 4)
#   (3, 4, 5)

Notes: Generalized multi value iteration

Creating and unpacking a list of staggered iterables allows us to generalize iterating with multiple values derived from same iterable. It is to be noted that this works for iterables and not iterators.

Multiple distinct values from an iterator

If multiple values are needed from a list of numbers, where the next iteration moves the pointer to next new value - then we can use an iterator. An iterator keeps track of the last value it has released.

Py3: Multiple values using iterator

#   create an iterator
nums = [1,2,3,4,5,6,7,8,9]
itr = iter(nums)

#   request 3 values from iterator each loop
#   same as: for triplet in zip(itr, itr, itr):
for triplet in zip(*[itr]*3):
    print(triplet)

#=  (1, 2, 3)
#   (4, 5, 6)
#   (7, 8, 9)

Notes: Iterator instead of iterables

The difference is stark when we convert an iterable into an iterator. The pointer for an iterable being queried by a zip per cycle moves by a single value. When zip requests multiple values from an iterator, the pointer moves by multiple positions. So the iterator version provides multiple values without repetition of the values.

Zip as transpose

We can think of zip as a way to change the ordering of a two dimensional data structure. The combinations are reversible by multiple zip operations.

Py3: Reversible zip transpositions

a = (1,2,3,4)
b = (6,7,8,9)

#   zip two iterables and expand into list
z = list(zip(a,b))
#=  [(1,6), (2,7), (3,8), (4,9)]


#   create initial list of two iterables
c = [a,b]
#=  [(1,2,3,4), (6,7,8,9)]

#   apply zip; same as zip(a,b)
z1 = list(zip(*c))
#=  [(1,6), (2,7), (3,8), (4,9)]

#   reapply zip, to get back initial list
z2 = list(zip(*z1))
#=  [(1,2,3,4), (6,7,8,9)]    

Notes: Transposing using zip

Zip rearranges elements within a two dimensional data structure. We can think about this as rows and columns. Zip converts between rows and columns. When we finally look at each row as a group, we notice that the operation reverts back to original when zip is applied twice sequentially.

References

Popular content

python programming

Read and write lists with Pickle, Array and Pandas

python programming

Flatten nested list or generate blocks of nested lists

python programming

For loop and control statements

python programming

Clear list using inplace and standard methods

python programming

List comprehension with nested conditions

python programming

Concatenate list elements using add, append, extend

python programming

Enumerate and custom counters like skip and loop

python programming

Count number of elements, and memory allocated

python programming

Remove duplicate list elements

python programming

Statistics with numeric lists of integers, fractions, and decimals.

New content

python programming

Read and write lists with Pickle, Array and Pandas

python programming

Is element in list?

python programming

Dictionary merge common key groups

python programming

Packaging loops with zip

python programming

Concatenate list elements using add, append, extend

python programming

List comprehension with nested conditions

python programming

Flatten nested list or generate blocks of nested lists

python programming

Enumerate and custom counters like skip and loop

python programming

Range integer sequences

python programming

For loop and control statements