Zipping (computer science)

From Wikipedia, the free encyclopedia
(Redirected from Zip (higher-order function))

Template:Short description Script error: No such module "about". In computer science, zipping is a function which maps a tuple of sequences into a sequence of tuples. This name zip derives from the action of a zipper in that it interleaves two formerly disjoint sequences. The inverse function is unzip.

Example

Given the three words cat, fish and be where |cat| is 3, |fish| is 4 and |be| is 2. Let denote the length of the longest word which is fish; =4. The zip of cat, fish, be is then 4 tuples of elements:

(c,f,b)(a,i,e)(t,s,#)(#,h,#)

where # is a symbol not in the original alphabet. In Haskell this truncates to the shortest sequence _, where _=2:

zip3 "cat" "fish" "be"
-- [('c','f','b'),('a','i','e')]

Definition

Let Σ be an alphabet, # a symbol not in Σ.

Let x1x2... x|x|, y1y2... y|y|, z1z2... z|z|, ... be n words (i.e. finite sequences) of elements of Σ. Let denote the length of the longest word, i.e. the maximum of |x|, |y|, |z|, ... .

The zip of these words is a finite sequence of n-tuples of elements of (Σ ∪ {#}), i.e. an element of ((Σ{#})n):

(x1,y1,)(x2,y2,)(x,y,),

where for any index i > Template:Abs, the wi is #.

The zip of x, y, z, ... is denoted zip(x, y, z, ...) or xyz ⋆ ...

The inverse to zip is sometimes denoted unzip.

A variation of the zip operation is defined by:

(x1,y1,)(x2,y2,)(x_,y_,)

where _ is the minimum length of the input words. It avoids the use of an adjoined element #, but destroys information about elements of the input sequences beyond _.

In programming languages

Zip functions are often available in programming languages, often referred to as Page Template:Mono/styles.css has no content.zip. In Lisp-dialects one can simply Page Template:Mono/styles.css has no content.map the desired function over the desired lists, Page Template:Mono/styles.css has no content.map is variadic in Lisp so it can take an arbitrary number of lists as argument. An example from Clojure:[1]

;; `nums' contains an infinite list of numbers (0 1 2 3 ...)
(def nums (range))
(def tens [10 20 30])
(def firstname "Alice")

;; To zip (0 1 2 3 ...) and [10 20 30] into a vector, invoke `map vector' on them; same with list
(map vector nums tens)           ; ⇒ ([0 10] [1 20] [2 30])
(map list nums tens)             ; ⇒ ((0 10) (1 20) (2 30))
(map str nums tens)              ; ⇒ ("010" "120" "230")

;; `map' truncates to the shortest sequence; note missing \c and \e from "Alice"
(map vector nums tens firstname) ; ⇒ ([0 10 \A] [1 20 \l] [2 30 \i])
(map str nums tens firstname)    ; ⇒ ("010A" "120l" "230i")

;; To unzip, apply `map vector' or `map list'
(apply map list (map vector nums tens firstname))
;; ⇒ ((0 1 2) (10 20 30) (\A \l \i))

In Common Lisp:

(defparameter nums '(1 2 3))
(defparameter tens '(10 20 30))
(defparameter firstname "Alice")

(mapcar #'list nums tens)
;; ⇒ ((1 10) (2 20) (3 30))

(mapcar #'list nums tens (coerce firstname 'list))
;; ⇒ ((1 10 #\A) (2 20 #\l) (3 30 #\i)) — truncates on shortest list

;; Unzips
(apply #'mapcar #'list (mapcar #'list nums tens (coerce firstname 'list)))
;; ⇒ ((1 2 3) (10 20 30) (#\A #\l #\i))

Languages such as Python provide a Page Template:Mono/styles.css has no content.zip() function.[2] Page Template:Mono/styles.css has no content.zip() in conjunction with the Page Template:Mono/styles.css has no content.* operator unzips a list:[2]

>>> nums = [1, 2, 3]
>>> tens = [10, 20, 30]
>>> firstname = 'Alice'

>>> zipped = list(zip(nums, tens))
>>> zipped
[(1, 10), (2, 20), (3, 30)]

>>> list(zip(*zipped)) # unzip
[(1, 2, 3), (10, 20, 30)]

>>> zipped2 = list(zip(nums, tens, list(firstname)))
>>> zipped2 # zip, truncates on shortest
[(1, 10, 'A'), (2, 20, 'l'), (3, 30, 'i')] 
>>> list(zip(*zipped2)) # unzip
[(1, 2, 3), (10, 20, 30), ('A', 'l', 'i')]

Haskell has a method of zipping sequences but requires a specific function for each arity (Page Template:Mono/styles.css has no content.zip for two sequences, Page Template:Mono/styles.css has no content.zip3 for three etc.),[3] similarly the functions Page Template:Mono/styles.css has no content.unzip and Page Template:Mono/styles.css has no content.unzip3 are available for unzipping:

-- nums contains an infinite list of numbers [1, 2, 3, ...] 
nums = [1..]
tens = [10, 20, 30]
firstname = "Alice"

zip nums tens
-- ⇒ [(1,10), (2,20), (3,30)] — zip, truncates infinite list
unzip $ zip nums tens
-- ⇒ ([1,2,3], [10,20,30]) — unzip

zip3 nums tens firstname
-- ⇒ [(1,10,'A'), (2,20,'l'), (3,30,'i')] — zip, truncates
unzip3 $ zip3 nums tens firstname
-- ⇒ ([1,2,3], [10,20,30], "Ali") — unzip

Language comparison

List of languages by support of zip:

Zip in various languages
Language Zip Zip 3 lists Zip n lists Notes
Chapel Page Template:Mono/styles.css has no content.zip (iter1 iter2) Page Template:Mono/styles.css has no content.zip (iter1 iter2 iter3) Page Template:Mono/styles.css has no content.zip (iter1 ... itern) The shape of each iterator, the rank and the extents in each dimension, must be identical.[4]
Clojure Page Template:Mono/styles.css has no content.Template:Codett list1 list2)
Page Template:Mono/styles.css has no content.Template:Codett list1 list2)
Page Template:Mono/styles.css has no content.Template:Codett list1 list2 list3)
Page Template:Mono/styles.css has no content.Template:Codett list1 list2 list3)
Page Template:Mono/styles.css has no content.Template:Codett list1listn)
Page Template:Mono/styles.css has no content.Template:Codett list1listn)
Stops after the length of the shortest list.
Common Lisp Template:Codett Template:Codett Template:Codett Stops after the length of the shortest list.
D Page Template:Mono/styles.css has no content.zip(range1, range2)
Page Template:Mono/styles.css has no content.range1.zip(range2)
Page Template:Mono/styles.css has no content.zip(range1, range2,range3)
Page Template:Mono/styles.css has no content.range1.zip(range2, range3)
Page Template:Mono/styles.css has no content.zip(range1, …, rangeN)
Page Template:Mono/styles.css has no content.range1.zip(…, rangeN)
The stopping policy defaults to shortest and can be optionally provided as shortest, longest, or requiring the same length.[5] The second form is an example of UFCS.
F# Page Template:Mono/styles.css has no content.List.zip list1 list2
Page Template:Mono/styles.css has no content.Seq.zip source1 source2
Page Template:Mono/styles.css has no content.Array.zip array1 array2
Page Template:Mono/styles.css has no content.List.zip3 list1 list2 list3
Page Template:Mono/styles.css has no content.Seq.zip3 source1 source2 source3
Page Template:Mono/styles.css has no content.Array.zip3 array1 array2 array3
Haskell Page Template:Mono/styles.css has no content.zip list1 list2 Page Template:Mono/styles.css has no content.zip3 list1 list2 list3 Page Template:Mono/styles.css has no content.zipn list1listn Page Template:Mono/styles.css has no content.zipn for n > 3 is available in the module Data.List. Stops after the shortest list ends.
Python Page Template:Mono/styles.css has no content.zip(list1, list2) Page Template:Mono/styles.css has no content.zip(list1, list2, list3) Page Template:Mono/styles.css has no content.zip(list1, …, listn) Page Template:Mono/styles.css has no content.zip() and Page Template:Mono/styles.css has no content.map() (3.x) stops after the shortest list ends, whereas Page Template:Mono/styles.css has no content.map() (2.x) and Page Template:Mono/styles.css has no content.itertools.zip_longest() (3.x) extends the shorter lists with Page Template:Mono/styles.css has no content.None items
Ruby Page Template:Mono/styles.css has no content.list1.zip(list2) Page Template:Mono/styles.css has no content.list1.zip(list2, list3) Page Template:Mono/styles.css has no content.list1.zip(list1, .., listn) When the list being executed upon (list1) is shorter than the lists being zipped the resulting list is the length of list1. If list1 is longer nil values are used to fill the missing values[6]
Scala Page Template:Mono/styles.css has no content.list1.zip(list2) If one of the two collections is longer than the other, its remaining elements are ignored.[7]
Unzip in various languages
Language Unzip Unzip 3 tuples Unzip n tuples Notes
Clojure Page Template:Mono/styles.css has no content.Template:Codett ziplist) Page Template:Mono/styles.css has no content.Template:Codett ziplist) Page Template:Mono/styles.css has no content.Template:Codett ziplist)
Common Lisp Template:Codett Template:Codett Template:Codett
F# Page Template:Mono/styles.css has no content.List.unzip list1 list2
Page Template:Mono/styles.css has no content.Seq.unzip source1 source2
Page Template:Mono/styles.css has no content.Array.unzip array1 array2
Page Template:Mono/styles.css has no content.List.unzip3 list1 list2 list3
Page Template:Mono/styles.css has no content.Seq.unzip3 source1 source2 source3
Page Template:Mono/styles.css has no content.Array.unzip3 array1 array2 array3
Haskell Page Template:Mono/styles.css has no content.unzip ziplist Page Template:Mono/styles.css has no content.unzip3 ziplist Page Template:Mono/styles.css has no content.unzipn ziplist Page Template:Mono/styles.css has no content.unzipn for n > 3 is available in the module Page Template:Mono/styles.css has no content.Data.List.
Python Page Template:Mono/styles.css has no content.zip(*zipvlist) Page Template:Mono/styles.css has no content.zip(*zipvlist) Page Template:Mono/styles.css has no content.zip(*zipvlist)

See also

Lua error in mw.title.lua at line 404: bad argument #2 to 'title.new' (unrecognized namespace name 'Portal').

References

  1. ^ map from ClojureDocs
  2. ^ a b map(function, iterable, ...) from section Built-in Functions from Python v2.7.2 documentation
  3. ^ zip :: [a] -> [b] -> [(a, b)] from Prelude, Basic libraries
  4. ^ Page Module:Citation/CS1/styles.css has no content."Statements — Chapel Documentation 1.25".
  5. ^ Page Module:Citation/CS1/styles.css has no content."std.range - D Programming Language".
  6. ^ Page Module:Citation/CS1/styles.css has no content."Class: Array".
  7. ^ Page Module:Citation/CS1/styles.css has no content."IterableOps". scala-lang.org.