Mathwizurd.com is created by David Witten, a mathematics and computer science student at Vanderbilt University. For more information, see the "About" page.

## Jul 27 Itertools Demo

This will be a demo of Itertools, a python module used for iterables. It's really useful, and I couldn't find any good demos of itertools, so I decided to make one. I'll go through each function, and I'll give an example of each.

Note: for most or all of these, they must be converted into lists, or iterated through. In my examples, I generally didn't do that

# Infinite Iterators

## Count

`count(start=0, step=1) #count(10,2) = 10, 12, 14, 16, 18, 20, 22, 24, 26 ... `

### Example:

```def infinitePrimes(): #returns a generator of an infinite # of primes
yield 2
for i in count(3, 2):
if isPrime(i):
yield i```

## Cycle

`cycle(iterable) #cycle("ABCD") = A B C D A B C D A B C D A B C D ...`

### Example:

```def turn_based():
for n,i in enumerate(cycle(["Adam", "Will", "David", "Bob"])):
print("%(person)s's turn: "%{"person":i})
if n == 30:
break
#example output: David's turn```

## Repeat

```repeat(element [, n times]) #repeat(100, 4) = 100, 100, 100, 100
#repeat(30) = 30, 30, 30, 30, 30, 30, 30, 30 ...```

### Example:

```#Use as a stream of constant values to map or zip
list(map(pow, range(5), repeat(3)))
>>> [0, 1, 8, 27, 64]
list(zip(range(6), repeat(2)))
>>> [(0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (5, 2)]```

# Finite Iterators

## Accumulate

```accumulate(p [,func]) #list(accumulate(range(10))) =
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45] #list of triangular numbers
```

### Example:

```#List of factorials
list(accumulate(range(1, 10), lambda x,y: x*y)) = [1, 2, 6, 24, 120, 720, 5040, 40320, 362880]```

## Chain

`chain([1,2,3],[4,5,6]) -> [1,2,3,4,5,6]`

### Example:

```#If you want to combine many lists
array1 = [1,2,3]
array2 = [4,5,6]
array3 = [7,8,9]
bigArray = chain(array1, array2, array3)
#bigArray = [1,2,3,4,5,6,7,8,9]```

## Chain.from_iterable

`chain.from_iterable([[1,2,3],[4,5,6]]) -> [1,2,3,4,5,6]`

### Example:

`chain.from_iterable(repeat([1,2,3],4))  #[1,2,3,1,2,3,1,2,3,1,2,3]`

## Compress

Given an iterable, it outputs elements if the corresponding selector element would be true.

`compress("ABCDEF",[True, False, True, False, False, True]) -> ["A","C","F"]`

### Example:

```#Easy way to randomly keep parts of a list
compress(range(1,11), [randrange(2) for i in range(10)])```

## Dropwhile (opposite is Takewhile)

When the rule fails, it keeps all the elements in the list.

Takewhile: When rule is still true, it keeps the elements.

`dropwhile(lambda x: x > 5, [8, 6, 4, 6, 19]) -> [4,6,19]`

### Example:

```#Given a list of ID's, take out all of the elements before an ID
myID = "A18374342"
newList = list(dropwhile(lambda x: x != myID, ["D72578853","E13312524","F97086753","A18374342","J99928883","K93788275"]))
```

## Filterfalse

Opposite of filter, keeps it when condition is false

```filterfalse(lambda x: x%4, range(15)) -> [0, 4, 8, 12]
```

## Groupby

Given a list, it returns distinct term, and groups.

```for element, group in groupby("AAABCCCDEEEFFFFIIIIKJJJ"):
print(element, list(group))

>>>A ['A', 'A', 'A']
B ['B']
C ['C', 'C', 'C']
D ['D']
E ['E', 'E', 'E']
F ['F', 'F', 'F', 'F']
I ['I', 'I', 'I', 'I']
K ['K']
J ['J', 'J', 'J']```

### Example:

```#Turn groups into a list of single elements.
#[1,1,1,2,3,4,4,4] -> [1,2,3,4]
[el for el, gr in groupby([1,1,1,2,3,4,4,4])]
>>> [1,2,3,4]```

## Starmap

Differs from map, because map considers each element a single element. Starmap only works when the list is made up of iterables. It maps each list as func(*element).

```Affect a single element:

[1.0, 2.0, 3.0] -> [1,2,3]
map(int, [1.0,2.0,3.0])

Affect a list:

[[1,2],[3,4],[5,6]] -> [3,7,11]
starmap(lambda a,b: a + b, [[1,2],[3,4],[5,6]])
```

## Zip_longest

Similar to zip, but you can designate a fill value.

```#Given money, and people
zip_longest(["David", "Bob","Joe","Armand","Ray"], [100, 130, 90], fillvalue = 0)
>>> [('David', 100), ('Bob', 130), ('Joe', 90), ('Armand', 0), ('Ray', 0)]```

# Combinatoric Functions

## Product

This is the cartesian product of multiple iterables. product(a,b) is equal to [(i,j) for i in a for j in b].

```#Basic cartesian product
product(range(1,3), "ASDF")
>>> [(1, 'A'), (1, 'S'), (1, 'D'), (1, 'F'), (2, 'A'), (2, 'S'), (2, 'D'), (2, 'F')]```

### Example from AI Rock Paper Scissors

```{i:0 for i in list(itertools.product("012",repeat=3))}
#{(0,0,0):0, (0,0,1):0, (0,1,0):0, ... (1,1,1):0}```

## Permutations

Given a set P, and a length R, it returns the number of r-length subsets of P, in no order. R can be left blank, then it would return the permutations of set P

### Example

```permutations("ABCD",2)
>>> AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC
permutations("ABCD")

## Combinations

Same as permutations, but it's in sorted order. Also, unlike permutations, r has to be specified.

```combinations("ABCD",2)
>>> AB, AC, AD, BC, BD, CD
```

## Combinations_with_replacement

Very similar to combinations, but terms can be repeated.

```combinations_with_replacement("ABCD",3)
>>> AAA, AAB, AAC, AAD, ABB, ABC, ABD, ACC, ACD, ADD, BBB, BBC, BBD, BCC, BCD, BDD, CCC, CCD, CDD, DDD```

I hope that helped; Itertools is a really useful module in Python, and there aren't many functions that have as many useful function as Itertools.

David Witten