Skip to content

Instantly share code, notes, and snippets.

@refraction-ray
Created February 24, 2019 02:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save refraction-ray/4ac739ff0bc1a08fafc4cb56d376ce14 to your computer and use it in GitHub Desktop.
Save refraction-ray/4ac739ff0bc1a08fafc4cb56d376ce14 to your computer and use it in GitHub Desktop.
A minimal tutorial on itertools module in python
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# itertools in python\n",
"**Reference**: [doc](https://docs.python.org/3.6/library/itertools.html)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import itertools"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This module is used to construct iterables in certain way.\n",
"In general, functions in this module, take one or more exsiting iterables as input,\n",
"and give a new iterable as output."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## accumulate"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is like a iterable version of `reduce`, instead of giving only a final value, it gives the process list of computation in some sense."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[11, 3, 3, 3, 3]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.accumulate([11,3,9,7,5],func=min)) # the func kw input is the function used for reduce"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## chain"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function just chain different iterables together"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 2, 3, 4, 5, 6]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.chain([1,2,3],[4,5],[6]))"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 2, 3, 4, [5, 6], 7, 8]"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"## flatten one level of nested list by chain\n",
"list(itertools.chain(*[[1,2],[3,4,[5,6]],[7,8]]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## combinations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"give combinations of given iterable with given length"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 2, 3),\n",
" (1, 2, 1),\n",
" (1, 2, 2),\n",
" (1, 2, 1),\n",
" (1, 3, 1),\n",
" (1, 3, 2),\n",
" (1, 3, 1),\n",
" (1, 1, 2),\n",
" (1, 1, 1),\n",
" (1, 2, 1),\n",
" (2, 3, 1),\n",
" (2, 3, 2),\n",
" (2, 3, 1),\n",
" (2, 1, 2),\n",
" (2, 1, 1),\n",
" (2, 2, 1),\n",
" (3, 1, 2),\n",
" (3, 1, 1),\n",
" (3, 2, 1),\n",
" (1, 2, 1)]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.combinations([1,2,3,1,2,1],3)) # the result is sorted as the given iterable"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l'),\n",
" ('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'd'),\n",
" ('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'l', 'd'),\n",
" ('h', 'e', 'l', 'l', 'o', ' ', 'w', 'r', 'l', 'd'),\n",
" ('h', 'e', 'l', 'l', 'o', ' ', 'o', 'r', 'l', 'd'),\n",
" ('h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'),\n",
" ('h', 'e', 'l', 'l', ' ', 'w', 'o', 'r', 'l', 'd'),\n",
" ('h', 'e', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'),\n",
" ('h', 'e', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'),\n",
" ('h', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'),\n",
" ('e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd')]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.combinations(\"hello world\",10))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# possible implementation\n",
"def combinations(iterable, r):\n",
" # combinations('ABCD', 2) --> AB AC AD BC BD CD\n",
" # combinations(range(4), 3) --> 012 013 023 123\n",
" \n",
" pool = tuple(iterable) ## in comment below, suppose the iterable is 0,2,...n-1, same as the indices\n",
" n = len(pool)\n",
" if r > n:\n",
" return\n",
" indices = list(range(r))\n",
" yield tuple(pool[i] for i in indices) ## yield the first combination as 0...r-1\n",
" while True:\n",
" for i in reversed(range(r)):\n",
" if indices[i] != i + n - r: # check against the final combination n-r ... n-1\n",
" break\n",
" else: ## if no break, then all combinations have been exausted, return to end the generator\n",
" return\n",
" indices[i] += 1\n",
" for j in range(i+1, r):\n",
" indices[j] = indices[j-1] + 1 ## indiced after i in a increasing natural order\n",
" yield tuple(pool[i] for i in indices) ## generate this round of combinations based on new indices"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## combinations with replacement"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similar to combinations, but in the output set, the elements can be duplicated though only one occurence in the input"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 1, 1, 1, 1),\n",
" (1, 1, 1, 1, 2),\n",
" (1, 1, 1, 1, 3),\n",
" (1, 1, 1, 2, 2),\n",
" (1, 1, 1, 2, 3),\n",
" (1, 1, 1, 3, 3),\n",
" (1, 1, 2, 2, 2),\n",
" (1, 1, 2, 2, 3),\n",
" (1, 1, 2, 3, 3),\n",
" (1, 1, 3, 3, 3),\n",
" (1, 2, 2, 2, 2),\n",
" (1, 2, 2, 2, 3),\n",
" (1, 2, 2, 3, 3),\n",
" (1, 2, 3, 3, 3),\n",
" (1, 3, 3, 3, 3),\n",
" (2, 2, 2, 2, 2),\n",
" (2, 2, 2, 2, 3),\n",
" (2, 2, 2, 3, 3),\n",
" (2, 2, 3, 3, 3),\n",
" (2, 3, 3, 3, 3),\n",
" (3, 3, 3, 3, 3)]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.combinations_with_replacement([1,2,3],5))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## possible implementation\n",
"def combinations_with_replacement(iterable, r):\n",
" # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC\n",
" pool = tuple(iterable)\n",
" n = len(pool)\n",
" if not n and r: # no iterable, just end\n",
" return\n",
" indices = [0] * r\n",
" yield tuple(pool[i] for i in indices) # yield the first combination 00000\n",
" while True:\n",
" for i in reversed(range(r)):\n",
" if indices[i] != n - 1: # check against the final configuration n-1,n-1...n-1\n",
" break\n",
" else: # if no break, the generator is finished\n",
" return\n",
" indices[i:] = [indices[i] + 1] * (r - i) # update elements after the first non n-1 term plusing one\n",
" yield tuple(pool[i] for i in indices)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## compress"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"something very similar to a mask on the iterable, the second iterable serves as the mask of the first one"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 3, 5]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.compress([1,2,3,4,5],[1,0,1,0,1]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## count"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"count from the start value, with one step more each turn, **caution**: the returned iterator is infinite"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"10\n",
"12\n",
"14\n",
"16\n",
"18\n",
"20\n",
"22\n",
"24\n",
"26\n",
"28\n",
"30\n"
]
}
],
"source": [
"c = itertools.count(10,2)\n",
"for i, n in enumerate(c):\n",
" if i>10:\n",
" break\n",
" print(n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## cycle"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"generate element according to a given iterator infinite round, **Caution**: infinite generator"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n",
"1\n",
"2\n",
"3\n",
"1\n",
"2\n",
"3\n",
"1\n",
"2\n",
"3\n",
"1\n"
]
}
],
"source": [
"c = itertools.cycle([1,2,3])\n",
"for i, n in enumerate(c):\n",
" if i>12:\n",
" break\n",
" print(n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## dropwhile"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"the first argument is the predicate function, when first **false** evaluation met, **generate all element behind regradless of their boolean wrt the first argument**. Be caution about the meaning of this function, which is sort of unnatural"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[5, 7, 9, 1]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.dropwhile(lambda x:x<5, [3,5,7,9,1]))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[3, 5, 7, 9, 1]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.dropwhile(lambda x:x>5, [3,5,7,9,1]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## filterfalse"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"return all elements evaluated to false, contrary to the builtin `filter` function"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[5, 7, 9]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.filterfalse(lambda x:x<5, [3,5,7,9,1]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## groupby"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"return iterator of iterators, each group of iterator is group by the key function with same return value, the input data should already be sorted by the key, because the implementation is to detect the change of the key value and then yield"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(2, <itertools._grouper at 0x10d0ed7b8>),\n",
" (3, <itertools._grouper at 0x10d0ed908>)]"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"gb = list(itertools.groupby([(1,2),(2,2),(2,3),(3,3),(1,3)],key= lambda x:x[1]))\n",
"gb"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"## right way\n",
"l = []\n",
"for i in itertools.groupby([(1,2),(2,2),(2,3),(3,3),(1,3)],key= lambda x:x[1]):\n",
" l.append(list(i[1]))"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[(1, 2), (2, 2)], [(2, 3), (3, 3), (1, 3)]]"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"l"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Caution:** The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list:\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# wrongway\n",
"list(gb[0][1]) ## the other elements are gone since it is a generator"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## islice"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.islice(range(20),2,8,2)) == list(range(20))[2:8:2] # one line is the whole story of islice"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## permutations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"order matter version of combination"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[('a', 'b'),\n",
" ('a', 'c'),\n",
" ('a', 'd'),\n",
" ('b', 'a'),\n",
" ('b', 'c'),\n",
" ('b', 'd'),\n",
" ('c', 'a'),\n",
" ('c', 'b'),\n",
" ('c', 'd'),\n",
" ('d', 'a'),\n",
" ('d', 'b'),\n",
" ('d', 'c')]"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.permutations(\"abcd\",2))"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 2),\n",
" (1, 3),\n",
" (1, 2),\n",
" (2, 1),\n",
" (2, 3),\n",
" (2, 2),\n",
" (3, 1),\n",
" (3, 2),\n",
" (3, 2),\n",
" (2, 1),\n",
" (2, 2),\n",
" (2, 3)]"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.permutations([1,2,3,2],2))"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [],
"source": [
"## possible implementation\n",
"def permutations(iterable, r=None):\n",
" # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC\n",
" # permutations(range(3)) --> 012 021 102 120 201 210\n",
" pool = tuple(iterable)\n",
" n = len(pool)\n",
" r = n if r is None else r\n",
" if r > n:\n",
" return\n",
" indices = list(range(n)) ## the first one is 0,1...r-1\n",
" cycles = list(range(n, n-r, -1)) ## cycle = n-1, n-2,... n-r+1 \n",
" ## the ith pos of cycle is the next larger ele pos after indices[i], which is indices[-j], and plus 1\n",
" ## if cycle[i]=0 after the -1 process, it means there is nothing larger than indices[i] after it\n",
" print(f\"initial indices: {indices}\")\n",
" print(f\"initial cycles: {cycles}\")\n",
" yield tuple(pool[i] for i in indices[:r])\n",
" while n:\n",
" print(\"-------new round of yield-------\")\n",
" for i in reversed(range(r)):\n",
" print(f\"i={i}\")\n",
" cycles[i] -= 1\n",
" if cycles[i] == 0:\n",
" print(f\"update cycles, since cycle[{i}] = 0\")\n",
" indices[i:] = indices[i+1:] + indices[i:i+1] # push the ith pos of indices to the back,\n",
" # come back to the initial pos of this cycle, still in increasing order after i\n",
" cycles[i] = n - i # reset the i pos of cycle to the original value, since the state of indices \n",
" # after ith pos is coming back to original increasing state\n",
" print(f\"cycles: {cycles}\")\n",
" print(f\"indices: {indices}\")\n",
" else: # cycle the i pos with later pos to make sure every element occur within the first r window\n",
" j = cycles[i] \n",
" print(f\"iterchange {i}, {-j} in indices since cycle[{i}]={j}\") # interchange i and the next larger one\n",
" indices[i], indices[-j] = indices[-j], indices[i] # the real cycle process\n",
" print(f\"cycles: {cycles}\")\n",
" print(f\"yield indices: {indices}\")\n",
" yield tuple(pool[i] for i in indices[:r])\n",
" print(\"-------break this round of yield---------\")\n",
" break\n",
" else: # if no break, end\n",
" return"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"initial indices: [0, 1, 2, 3, 4]\n",
"initial cycles: [5, 4, 3]\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [5, 4, 2]\n",
"yield indices: [0, 1, 3, 2, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [5, 4, 1]\n",
"yield indices: [0, 1, 4, 2, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [5, 4, 3]\n",
"indices: [0, 1, 2, 3, 4]\n",
"i=1\n",
"iterchange 1, -3 in indices since cycle[1]=3\n",
"cycles: [5, 3, 3]\n",
"yield indices: [0, 2, 1, 3, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [5, 3, 2]\n",
"yield indices: [0, 2, 3, 1, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [5, 3, 1]\n",
"yield indices: [0, 2, 4, 1, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [5, 3, 3]\n",
"indices: [0, 2, 1, 3, 4]\n",
"i=1\n",
"iterchange 1, -2 in indices since cycle[1]=2\n",
"cycles: [5, 2, 3]\n",
"yield indices: [0, 3, 1, 2, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [5, 2, 2]\n",
"yield indices: [0, 3, 2, 1, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [5, 2, 1]\n",
"yield indices: [0, 3, 4, 1, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [5, 2, 3]\n",
"indices: [0, 3, 1, 2, 4]\n",
"i=1\n",
"iterchange 1, -1 in indices since cycle[1]=1\n",
"cycles: [5, 1, 3]\n",
"yield indices: [0, 4, 1, 2, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [5, 1, 2]\n",
"yield indices: [0, 4, 2, 1, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [5, 1, 1]\n",
"yield indices: [0, 4, 3, 1, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [5, 1, 3]\n",
"indices: [0, 4, 1, 2, 3]\n",
"i=1\n",
"update cycles, since cycle[1] = 0\n",
"cycles: [5, 4, 3]\n",
"indices: [0, 1, 2, 3, 4]\n",
"i=0\n",
"iterchange 0, -4 in indices since cycle[0]=4\n",
"cycles: [4, 4, 3]\n",
"yield indices: [1, 0, 2, 3, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [4, 4, 2]\n",
"yield indices: [1, 0, 3, 2, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [4, 4, 1]\n",
"yield indices: [1, 0, 4, 2, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [4, 4, 3]\n",
"indices: [1, 0, 2, 3, 4]\n",
"i=1\n",
"iterchange 1, -3 in indices since cycle[1]=3\n",
"cycles: [4, 3, 3]\n",
"yield indices: [1, 2, 0, 3, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [4, 3, 2]\n",
"yield indices: [1, 2, 3, 0, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [4, 3, 1]\n",
"yield indices: [1, 2, 4, 0, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [4, 3, 3]\n",
"indices: [1, 2, 0, 3, 4]\n",
"i=1\n",
"iterchange 1, -2 in indices since cycle[1]=2\n",
"cycles: [4, 2, 3]\n",
"yield indices: [1, 3, 0, 2, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [4, 2, 2]\n",
"yield indices: [1, 3, 2, 0, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [4, 2, 1]\n",
"yield indices: [1, 3, 4, 0, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [4, 2, 3]\n",
"indices: [1, 3, 0, 2, 4]\n",
"i=1\n",
"iterchange 1, -1 in indices since cycle[1]=1\n",
"cycles: [4, 1, 3]\n",
"yield indices: [1, 4, 0, 2, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [4, 1, 2]\n",
"yield indices: [1, 4, 2, 0, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [4, 1, 1]\n",
"yield indices: [1, 4, 3, 0, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [4, 1, 3]\n",
"indices: [1, 4, 0, 2, 3]\n",
"i=1\n",
"update cycles, since cycle[1] = 0\n",
"cycles: [4, 4, 3]\n",
"indices: [1, 0, 2, 3, 4]\n",
"i=0\n",
"iterchange 0, -3 in indices since cycle[0]=3\n",
"cycles: [3, 4, 3]\n",
"yield indices: [2, 0, 1, 3, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [3, 4, 2]\n",
"yield indices: [2, 0, 3, 1, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [3, 4, 1]\n",
"yield indices: [2, 0, 4, 1, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [3, 4, 3]\n",
"indices: [2, 0, 1, 3, 4]\n",
"i=1\n",
"iterchange 1, -3 in indices since cycle[1]=3\n",
"cycles: [3, 3, 3]\n",
"yield indices: [2, 1, 0, 3, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [3, 3, 2]\n",
"yield indices: [2, 1, 3, 0, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [3, 3, 1]\n",
"yield indices: [2, 1, 4, 0, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [3, 3, 3]\n",
"indices: [2, 1, 0, 3, 4]\n",
"i=1\n",
"iterchange 1, -2 in indices since cycle[1]=2\n",
"cycles: [3, 2, 3]\n",
"yield indices: [2, 3, 0, 1, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [3, 2, 2]\n",
"yield indices: [2, 3, 1, 0, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [3, 2, 1]\n",
"yield indices: [2, 3, 4, 0, 1]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [3, 2, 3]\n",
"indices: [2, 3, 0, 1, 4]\n",
"i=1\n",
"iterchange 1, -1 in indices since cycle[1]=1\n",
"cycles: [3, 1, 3]\n",
"yield indices: [2, 4, 0, 1, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [3, 1, 2]\n",
"yield indices: [2, 4, 1, 0, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [3, 1, 1]\n",
"yield indices: [2, 4, 3, 0, 1]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [3, 1, 3]\n",
"indices: [2, 4, 0, 1, 3]\n",
"i=1\n",
"update cycles, since cycle[1] = 0\n",
"cycles: [3, 4, 3]\n",
"indices: [2, 0, 1, 3, 4]\n",
"i=0\n",
"iterchange 0, -2 in indices since cycle[0]=2\n",
"cycles: [2, 4, 3]\n",
"yield indices: [3, 0, 1, 2, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [2, 4, 2]\n",
"yield indices: [3, 0, 2, 1, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [2, 4, 1]\n",
"yield indices: [3, 0, 4, 1, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [2, 4, 3]\n",
"indices: [3, 0, 1, 2, 4]\n",
"i=1\n",
"iterchange 1, -3 in indices since cycle[1]=3\n",
"cycles: [2, 3, 3]\n",
"yield indices: [3, 1, 0, 2, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [2, 3, 2]\n",
"yield indices: [3, 1, 2, 0, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [2, 3, 1]\n",
"yield indices: [3, 1, 4, 0, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [2, 3, 3]\n",
"indices: [3, 1, 0, 2, 4]\n",
"i=1\n",
"iterchange 1, -2 in indices since cycle[1]=2\n",
"cycles: [2, 2, 3]\n",
"yield indices: [3, 2, 0, 1, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [2, 2, 2]\n",
"yield indices: [3, 2, 1, 0, 4]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [2, 2, 1]\n",
"yield indices: [3, 2, 4, 0, 1]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [2, 2, 3]\n",
"indices: [3, 2, 0, 1, 4]\n",
"i=1\n",
"iterchange 1, -1 in indices since cycle[1]=1\n",
"cycles: [2, 1, 3]\n",
"yield indices: [3, 4, 0, 1, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [2, 1, 2]\n",
"yield indices: [3, 4, 1, 0, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [2, 1, 1]\n",
"yield indices: [3, 4, 2, 0, 1]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [2, 1, 3]\n",
"indices: [3, 4, 0, 1, 2]\n",
"i=1\n",
"update cycles, since cycle[1] = 0\n",
"cycles: [2, 4, 3]\n",
"indices: [3, 0, 1, 2, 4]\n",
"i=0\n",
"iterchange 0, -1 in indices since cycle[0]=1\n",
"cycles: [1, 4, 3]\n",
"yield indices: [4, 0, 1, 2, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [1, 4, 2]\n",
"yield indices: [4, 0, 2, 1, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [1, 4, 1]\n",
"yield indices: [4, 0, 3, 1, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [1, 4, 3]\n",
"indices: [4, 0, 1, 2, 3]\n",
"i=1\n",
"iterchange 1, -3 in indices since cycle[1]=3\n",
"cycles: [1, 3, 3]\n",
"yield indices: [4, 1, 0, 2, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [1, 3, 2]\n",
"yield indices: [4, 1, 2, 0, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [1, 3, 1]\n",
"yield indices: [4, 1, 3, 0, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [1, 3, 3]\n",
"indices: [4, 1, 0, 2, 3]\n",
"i=1\n",
"iterchange 1, -2 in indices since cycle[1]=2\n",
"cycles: [1, 2, 3]\n",
"yield indices: [4, 2, 0, 1, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [1, 2, 2]\n",
"yield indices: [4, 2, 1, 0, 3]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [1, 2, 1]\n",
"yield indices: [4, 2, 3, 0, 1]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [1, 2, 3]\n",
"indices: [4, 2, 0, 1, 3]\n",
"i=1\n",
"iterchange 1, -1 in indices since cycle[1]=1\n",
"cycles: [1, 1, 3]\n",
"yield indices: [4, 3, 0, 1, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -2 in indices since cycle[2]=2\n",
"cycles: [1, 1, 2]\n",
"yield indices: [4, 3, 1, 0, 2]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"iterchange 2, -1 in indices since cycle[2]=1\n",
"cycles: [1, 1, 1]\n",
"yield indices: [4, 3, 2, 0, 1]\n",
"-------break this round of yield---------\n",
"-------new round of yield-------\n",
"i=2\n",
"update cycles, since cycle[2] = 0\n",
"cycles: [1, 1, 3]\n",
"indices: [4, 3, 0, 1, 2]\n",
"i=1\n",
"update cycles, since cycle[1] = 0\n",
"cycles: [1, 4, 3]\n",
"indices: [4, 0, 1, 2, 3]\n",
"i=0\n",
"update cycles, since cycle[0] = 0\n",
"cycles: [5, 4, 3]\n",
"indices: [0, 1, 2, 3, 4]\n"
]
},
{
"data": {
"text/plain": [
"[(0, 1, 2),\n",
" (0, 1, 3),\n",
" (0, 1, 4),\n",
" (0, 2, 1),\n",
" (0, 2, 3),\n",
" (0, 2, 4),\n",
" (0, 3, 1),\n",
" (0, 3, 2),\n",
" (0, 3, 4),\n",
" (0, 4, 1),\n",
" (0, 4, 2),\n",
" (0, 4, 3),\n",
" (1, 0, 2),\n",
" (1, 0, 3),\n",
" (1, 0, 4),\n",
" (1, 2, 0),\n",
" (1, 2, 3),\n",
" (1, 2, 4),\n",
" (1, 3, 0),\n",
" (1, 3, 2),\n",
" (1, 3, 4),\n",
" (1, 4, 0),\n",
" (1, 4, 2),\n",
" (1, 4, 3),\n",
" (2, 0, 1),\n",
" (2, 0, 3),\n",
" (2, 0, 4),\n",
" (2, 1, 0),\n",
" (2, 1, 3),\n",
" (2, 1, 4),\n",
" (2, 3, 0),\n",
" (2, 3, 1),\n",
" (2, 3, 4),\n",
" (2, 4, 0),\n",
" (2, 4, 1),\n",
" (2, 4, 3),\n",
" (3, 0, 1),\n",
" (3, 0, 2),\n",
" (3, 0, 4),\n",
" (3, 1, 0),\n",
" (3, 1, 2),\n",
" (3, 1, 4),\n",
" (3, 2, 0),\n",
" (3, 2, 1),\n",
" (3, 2, 4),\n",
" (3, 4, 0),\n",
" (3, 4, 1),\n",
" (3, 4, 2),\n",
" (4, 0, 1),\n",
" (4, 0, 2),\n",
" (4, 0, 3),\n",
" (4, 1, 0),\n",
" (4, 1, 2),\n",
" (4, 1, 3),\n",
" (4, 2, 0),\n",
" (4, 2, 1),\n",
" (4, 2, 3),\n",
" (4, 3, 0),\n",
" (4, 3, 1),\n",
" (4, 3, 2)]"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(permutations([0,1,2,3,4],3)) ## see the debug info to learn about how this implementation works"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## product"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cartesian product of the input iterator, multiple iterators can be taken as input"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 'h'),\n",
" (1, 'i'),\n",
" (2, 'h'),\n",
" (2, 'i'),\n",
" (3, 'h'),\n",
" (3, 'i'),\n",
" (4, 'h'),\n",
" (4, 'i')]"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.product([1,2,3,4],\"hi\"))"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 5, 1, 5),\n",
" (1, 5, 1, 6),\n",
" (1, 5, 1, 7),\n",
" (1, 5, 1, 8),\n",
" (1, 5, 2, 5),\n",
" (1, 5, 2, 6),\n",
" (1, 5, 2, 7),\n",
" (1, 5, 2, 8),\n",
" (1, 5, 3, 5),\n",
" (1, 5, 3, 6),\n",
" (1, 5, 3, 7),\n",
" (1, 5, 3, 8),\n",
" (1, 5, 4, 5),\n",
" (1, 5, 4, 6),\n",
" (1, 5, 4, 7),\n",
" (1, 5, 4, 8),\n",
" (1, 6, 1, 5),\n",
" (1, 6, 1, 6),\n",
" (1, 6, 1, 7),\n",
" (1, 6, 1, 8),\n",
" (1, 6, 2, 5),\n",
" (1, 6, 2, 6),\n",
" (1, 6, 2, 7),\n",
" (1, 6, 2, 8),\n",
" (1, 6, 3, 5),\n",
" (1, 6, 3, 6),\n",
" (1, 6, 3, 7),\n",
" (1, 6, 3, 8),\n",
" (1, 6, 4, 5),\n",
" (1, 6, 4, 6),\n",
" (1, 6, 4, 7),\n",
" (1, 6, 4, 8),\n",
" (1, 7, 1, 5),\n",
" (1, 7, 1, 6),\n",
" (1, 7, 1, 7),\n",
" (1, 7, 1, 8),\n",
" (1, 7, 2, 5),\n",
" (1, 7, 2, 6),\n",
" (1, 7, 2, 7),\n",
" (1, 7, 2, 8),\n",
" (1, 7, 3, 5),\n",
" (1, 7, 3, 6),\n",
" (1, 7, 3, 7),\n",
" (1, 7, 3, 8),\n",
" (1, 7, 4, 5),\n",
" (1, 7, 4, 6),\n",
" (1, 7, 4, 7),\n",
" (1, 7, 4, 8),\n",
" (1, 8, 1, 5),\n",
" (1, 8, 1, 6),\n",
" (1, 8, 1, 7),\n",
" (1, 8, 1, 8),\n",
" (1, 8, 2, 5),\n",
" (1, 8, 2, 6),\n",
" (1, 8, 2, 7),\n",
" (1, 8, 2, 8),\n",
" (1, 8, 3, 5),\n",
" (1, 8, 3, 6),\n",
" (1, 8, 3, 7),\n",
" (1, 8, 3, 8),\n",
" (1, 8, 4, 5),\n",
" (1, 8, 4, 6),\n",
" (1, 8, 4, 7),\n",
" (1, 8, 4, 8),\n",
" (2, 5, 1, 5),\n",
" (2, 5, 1, 6),\n",
" (2, 5, 1, 7),\n",
" (2, 5, 1, 8),\n",
" (2, 5, 2, 5),\n",
" (2, 5, 2, 6),\n",
" (2, 5, 2, 7),\n",
" (2, 5, 2, 8),\n",
" (2, 5, 3, 5),\n",
" (2, 5, 3, 6),\n",
" (2, 5, 3, 7),\n",
" (2, 5, 3, 8),\n",
" (2, 5, 4, 5),\n",
" (2, 5, 4, 6),\n",
" (2, 5, 4, 7),\n",
" (2, 5, 4, 8),\n",
" (2, 6, 1, 5),\n",
" (2, 6, 1, 6),\n",
" (2, 6, 1, 7),\n",
" (2, 6, 1, 8),\n",
" (2, 6, 2, 5),\n",
" (2, 6, 2, 6),\n",
" (2, 6, 2, 7),\n",
" (2, 6, 2, 8),\n",
" (2, 6, 3, 5),\n",
" (2, 6, 3, 6),\n",
" (2, 6, 3, 7),\n",
" (2, 6, 3, 8),\n",
" (2, 6, 4, 5),\n",
" (2, 6, 4, 6),\n",
" (2, 6, 4, 7),\n",
" (2, 6, 4, 8),\n",
" (2, 7, 1, 5),\n",
" (2, 7, 1, 6),\n",
" (2, 7, 1, 7),\n",
" (2, 7, 1, 8),\n",
" (2, 7, 2, 5),\n",
" (2, 7, 2, 6),\n",
" (2, 7, 2, 7),\n",
" (2, 7, 2, 8),\n",
" (2, 7, 3, 5),\n",
" (2, 7, 3, 6),\n",
" (2, 7, 3, 7),\n",
" (2, 7, 3, 8),\n",
" (2, 7, 4, 5),\n",
" (2, 7, 4, 6),\n",
" (2, 7, 4, 7),\n",
" (2, 7, 4, 8),\n",
" (2, 8, 1, 5),\n",
" (2, 8, 1, 6),\n",
" (2, 8, 1, 7),\n",
" (2, 8, 1, 8),\n",
" (2, 8, 2, 5),\n",
" (2, 8, 2, 6),\n",
" (2, 8, 2, 7),\n",
" (2, 8, 2, 8),\n",
" (2, 8, 3, 5),\n",
" (2, 8, 3, 6),\n",
" (2, 8, 3, 7),\n",
" (2, 8, 3, 8),\n",
" (2, 8, 4, 5),\n",
" (2, 8, 4, 6),\n",
" (2, 8, 4, 7),\n",
" (2, 8, 4, 8),\n",
" (3, 5, 1, 5),\n",
" (3, 5, 1, 6),\n",
" (3, 5, 1, 7),\n",
" (3, 5, 1, 8),\n",
" (3, 5, 2, 5),\n",
" (3, 5, 2, 6),\n",
" (3, 5, 2, 7),\n",
" (3, 5, 2, 8),\n",
" (3, 5, 3, 5),\n",
" (3, 5, 3, 6),\n",
" (3, 5, 3, 7),\n",
" (3, 5, 3, 8),\n",
" (3, 5, 4, 5),\n",
" (3, 5, 4, 6),\n",
" (3, 5, 4, 7),\n",
" (3, 5, 4, 8),\n",
" (3, 6, 1, 5),\n",
" (3, 6, 1, 6),\n",
" (3, 6, 1, 7),\n",
" (3, 6, 1, 8),\n",
" (3, 6, 2, 5),\n",
" (3, 6, 2, 6),\n",
" (3, 6, 2, 7),\n",
" (3, 6, 2, 8),\n",
" (3, 6, 3, 5),\n",
" (3, 6, 3, 6),\n",
" (3, 6, 3, 7),\n",
" (3, 6, 3, 8),\n",
" (3, 6, 4, 5),\n",
" (3, 6, 4, 6),\n",
" (3, 6, 4, 7),\n",
" (3, 6, 4, 8),\n",
" (3, 7, 1, 5),\n",
" (3, 7, 1, 6),\n",
" (3, 7, 1, 7),\n",
" (3, 7, 1, 8),\n",
" (3, 7, 2, 5),\n",
" (3, 7, 2, 6),\n",
" (3, 7, 2, 7),\n",
" (3, 7, 2, 8),\n",
" (3, 7, 3, 5),\n",
" (3, 7, 3, 6),\n",
" (3, 7, 3, 7),\n",
" (3, 7, 3, 8),\n",
" (3, 7, 4, 5),\n",
" (3, 7, 4, 6),\n",
" (3, 7, 4, 7),\n",
" (3, 7, 4, 8),\n",
" (3, 8, 1, 5),\n",
" (3, 8, 1, 6),\n",
" (3, 8, 1, 7),\n",
" (3, 8, 1, 8),\n",
" (3, 8, 2, 5),\n",
" (3, 8, 2, 6),\n",
" (3, 8, 2, 7),\n",
" (3, 8, 2, 8),\n",
" (3, 8, 3, 5),\n",
" (3, 8, 3, 6),\n",
" (3, 8, 3, 7),\n",
" (3, 8, 3, 8),\n",
" (3, 8, 4, 5),\n",
" (3, 8, 4, 6),\n",
" (3, 8, 4, 7),\n",
" (3, 8, 4, 8),\n",
" (4, 5, 1, 5),\n",
" (4, 5, 1, 6),\n",
" (4, 5, 1, 7),\n",
" (4, 5, 1, 8),\n",
" (4, 5, 2, 5),\n",
" (4, 5, 2, 6),\n",
" (4, 5, 2, 7),\n",
" (4, 5, 2, 8),\n",
" (4, 5, 3, 5),\n",
" (4, 5, 3, 6),\n",
" (4, 5, 3, 7),\n",
" (4, 5, 3, 8),\n",
" (4, 5, 4, 5),\n",
" (4, 5, 4, 6),\n",
" (4, 5, 4, 7),\n",
" (4, 5, 4, 8),\n",
" (4, 6, 1, 5),\n",
" (4, 6, 1, 6),\n",
" (4, 6, 1, 7),\n",
" (4, 6, 1, 8),\n",
" (4, 6, 2, 5),\n",
" (4, 6, 2, 6),\n",
" (4, 6, 2, 7),\n",
" (4, 6, 2, 8),\n",
" (4, 6, 3, 5),\n",
" (4, 6, 3, 6),\n",
" (4, 6, 3, 7),\n",
" (4, 6, 3, 8),\n",
" (4, 6, 4, 5),\n",
" (4, 6, 4, 6),\n",
" (4, 6, 4, 7),\n",
" (4, 6, 4, 8),\n",
" (4, 7, 1, 5),\n",
" (4, 7, 1, 6),\n",
" (4, 7, 1, 7),\n",
" (4, 7, 1, 8),\n",
" (4, 7, 2, 5),\n",
" (4, 7, 2, 6),\n",
" (4, 7, 2, 7),\n",
" (4, 7, 2, 8),\n",
" (4, 7, 3, 5),\n",
" (4, 7, 3, 6),\n",
" (4, 7, 3, 7),\n",
" (4, 7, 3, 8),\n",
" (4, 7, 4, 5),\n",
" (4, 7, 4, 6),\n",
" (4, 7, 4, 7),\n",
" (4, 7, 4, 8),\n",
" (4, 8, 1, 5),\n",
" (4, 8, 1, 6),\n",
" (4, 8, 1, 7),\n",
" (4, 8, 1, 8),\n",
" (4, 8, 2, 5),\n",
" (4, 8, 2, 6),\n",
" (4, 8, 2, 7),\n",
" (4, 8, 2, 8),\n",
" (4, 8, 3, 5),\n",
" (4, 8, 3, 6),\n",
" (4, 8, 3, 7),\n",
" (4, 8, 3, 8),\n",
" (4, 8, 4, 5),\n",
" (4, 8, 4, 6),\n",
" (4, 8, 4, 7),\n",
" (4, 8, 4, 8)]"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.product([1,2,3,4],[5,6,7,8],repeat=2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## possible implementation\n",
"def product(*args, repeat=1):\n",
" # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy\n",
" # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111\n",
" pools = [tuple(pool) for pool in args] * repeat # pools = [(A,B,C,D),(x,y), [A,B,C,D],[x,y]]\n",
" result = [[]]\n",
" for pool in pools:\n",
" result = [x+[y] for x in result for y in pool]\n",
" for prod in result:\n",
" yield tuple(prod)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## repeat"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It generates one thing forever, unless time argument is specified, **caution:** possible infinite generator"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.repeat(1, times=10))"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(map(pow, range(10), itertools.repeat(2)))"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"## a better map approach avoid repeat\n",
"list(map(lambda x: pow(x,2), range(10)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## startmap"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[32, 9, 1000]"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.starmap(pow, [(2,5), (3,2), (10,3)]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## simple implementation\n",
"def starmap(function, iterable):\n",
" # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000\n",
" for args in iterable:\n",
" yield function(*args)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## takewhile"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It generates elements from the second input as long as the first input func is evaluated to be true. Namely stop generator when the first false is met. **Caution:** make sure the meaning of this function, it is not so natural."
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1]"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.takewhile(lambda x: x<5, [1,6,9,1]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## tee"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This turns one iterator into multiple copies"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [],
"source": [
"ls = list(itertools.tee([1,2,3,4],5))"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([1, 2, 3, 4], [1, 2, 3, 4])"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(ls[0]),list(ls[1])"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<itertools._tee at 0x10d1d49c8>,\n",
" <itertools._tee at 0x10d1c5208>,\n",
" <itertools._tee at 0x10d1c5188>,\n",
" <itertools._tee at 0x10d1c4648>,\n",
" <itertools._tee at 0x10d1c46c8>]"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ls"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## zip_longest"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A more robust and general version of zip. The iterables can be in unequal length. The missing value is treated as fillvalue flag in the function."
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 5), (2, 6), (3, 7), (4, 8)]"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.zip_longest([1,2,3,4],[5,6,7,8]))"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 5), (2, 6), (3, 7), (4, 8), (None, 9)]"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.zip_longest([1,2,3,4],[5,6,7,8,9]))"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 5), (2, 6), (3, 7), (4, 8), ('*', 9), ('*', 10)]"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.zip_longest([1,2,3,4],[5,6,7,8,9,10],fillvalue='*'))"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(1, 5, 11), (2, 6, 12), (3, 7, 0), (4, 8, 0), (0, 9, 0), (0, 10, 0)]"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(itertools.zip_longest([1,2,3,4],[5,6,7,8,9,10],[11,12],fillvalue=0))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment