In [1]:
list(zip([1,2,3], ['a','b','c']))
Out[1]:
In [2]:
# iter() 함수는 iterator object를 리턴한다.
iter([1,2,3,4])
Out[2]:
In [3]:
# map 함수는 싱글파라메터 함수를 각각의 엘리먼트에 한방에 적용가능
list(map(len, ['abc', 'de', 'fghi']))
Out[3]:
In [4]:
list(map(sum, zip([1,2,3], [4,5,6])))
Out[4]:
In [5]:
# 입력받은 리스트를 n개로 쪼개는 함수인데, n이 커지면 커질수록 메모리를 많이 쓰는 단점이 있다.
def naive_grouper(inputs, n):
num_groups = len(inputs) // n
return [tuple(inputs[i*n:(i+1)*n]) for i in range(num_groups)]
In [6]:
nums = [1,2,3,4,5,6,7,8,9,10]
naive_grouper(nums, 2)
Out[6]:
In [7]:
# itertools 를 사용해서 좀 더 나은 함수를 만들 수 있다.
def better_grouper(inputs, n):
iters = [iter(inputs)] * n
return zip(*iters)
In [8]:
nums = [1,2,3,4,5,6,7,8,9,10]
# * 연산자는 n 개의 같은 이터레이터의 레퍼런스를 생성한다.
iters = [iter(nums)] * 2
list(id(itr) for itr in iters)
Out[8]:
In [9]:
print(*iters)
zip(*iters)
는 iters 안의 각 이터레이터를 돌면서 엘리먼트의 쌍으로 이루어진 이터레이터를 리턴한다.
In [10]:
list(better_grouper(nums, 2))
Out[10]:
In [11]:
# 4개로 나눠서 쪼개면 뒤에 9,10 이 짤림
# zip 은 모자라는 녀석은 그냥 무시함
list(better_grouper(nums, 4))
Out[11]:
In [12]:
# zip_longest 를 쓰면 짤리는 것도 iteration 가능
import itertools as it
x = [1,2,3,4,5]
y = ['a','b','c']
list(zip(x, y))
Out[12]:
In [13]:
list(it.zip_longest(x, y))
Out[13]:
In [14]:
# better_grouper 를 수정한 grouper 메서드를 만들자
import itertools as it
def grouper(inputs, n):
iters = [iter(inputs)] * n
return it.zip_longest(*iters)
In [15]:
nums = [1,2,3,4,5,6,7,8,9,10]
list(grouper(nums, 4))
Out[15]:
In [16]:
import itertools as it
bills = [20, 20, 20, 10, 10, 10, 10, 10, 5, 5, 1, 1, 1, 1, 1]
list(it.combinations(bills,3 ))
Out[16]:
위의 문제를 풀려면 1개부터 len(bills) 까지 꺼내는 루프를 돌면서 그 합이 100인것을 찾으면 된다.
In [17]:
makes_100 = []
for n in range(1, len(bills) + 1 ):
for combination in it.combinations(bills, n):
if sum(combination) == 100:
makes_100.append(combination)
set(makes_100)
Out[17]:
위의 결과를 보면 답은 5가지 인것을 알 수 있다.
문제를 조금 변경해보자.
50달러, 20달러, 10달러, 5달러, 1달러짜리를 가지고 100달러를 만드는 경우의 수는 몇가지가 있을까?
In [18]:
# 미리 정의된 셋이 없기때문에 만들어줘야 함. itertools_combinations_with_replacement() 함수를 쓰면 됨
list(it.combinations_with_replacement([1,2], 2))
Out[18]:
In [19]:
# 50, 20, 10, 5, 1 로 만들수 있는 경우의 수를 다 만들면 됨
# 1달러 100개면 100달러이므로 최대 길이를 100으로 하면 됨
bills = [50, 20, 10, 5, 1]
make_100 = []
for n in range(1, 101):
for combination in it.combinations_with_replacement(bills, n):
if sum(combination) == 100:
make_100.append(combination)
In [20]:
len(make_100)
Out[20]:
In [21]:
# 순열도 가능 (permutation)
list(it.permutations(['a', 'b', 'c']))
Out[21]:
In [22]:
def evens():
n = 0
while True:
yield n
n += 2
evens = evens()
list(next(evens) for _ in range(5))
Out[22]:
In [23]:
def odds():
n = 1
while True:
yield n
n += 2
odds = odds()
list(next(odds) for _ in range(5))
Out[23]:
In [24]:
counter = it.count()
list(next(counter) for _ in range(5))
Out[24]:
In [25]:
evens = it.count(step=2)
list(next(evens) for _ in range(5))
Out[25]:
In [26]:
odds = it.count(start=1, step=2)
list(next(odds) for _ in range(5))
Out[26]:
In [27]:
count_with_floats = it.count(start=0.5, step=0.75)
list(next(count_with_floats) for _ in range(5))
Out[27]:
In [28]:
negative_count = it.count(start=-1, step=0.5)
list(next(negative_count) for _ in range(5))
Out[28]:
In [29]:
list(zip(it.count(), ['a', 'b', 'c']))
Out[29]:
In [30]:
def fibs():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
In [31]:
def accumulate(inputs, func):
itr = iter(inputs)
prev = next(itr)
for cur in itr:
yield prev
prev = func(prev, cur)
In [32]:
list(it.accumulate([1,2,3,4,5]))
Out[32]:
In [33]:
list(it.accumulate([9,21,17,5,11,12,2,6], min))
Out[33]:
In [34]:
list(it.accumulate([1,2,3,4,5], lambda x ,y: (x + y) / 2))
Out[34]:
In [35]:
list(it.accumulate([1,2,3,4,5], lambda x,y : x - y))
Out[35]:
In [36]:
list(it.accumulate([1,2,3,4,5], lambda x,y : y - x))
Out[36]:
In [37]:
def first_order(p, q, initial_val):
return it.accumulate(it.repeat(initial_val), lambda s, _: p*s + q)
In [38]:
import itertools as it
it.count()
Out[38]:
In [39]:
it.count(start=1, step=2)
Out[39]:
In [40]:
it.repeat(2)
Out[40]:
In [41]:
it.repeat(2,5)
Out[41]:
In [ ]:
list(it.cycle(['a','b','c']))
In [ ]:
# 배열 곱하기
import itertools as it
list(it.product([1,2], ['a', 'b']))
In [ ]:
# itertools.tee
iter1, iter2 = it.tee(['a', 'b', 'c'], 2)
list(iter1)
In [ ]:
list(iter2)
In [ ]:
list(it.islice([1,2,3,4], 3))
In [ ]:
list(it.islice([1,2,3,4], 1, 2))
In [ ]:
list(it.chain('abc', [1,2,3]))