상세 컨텐츠

본문 제목

itertools

Python

by techbard 2025. 4. 1. 15:14

본문

반응형

 

# Sequence comparisons

import itertools

# define some lists
seq_1 = [1, 2, 3, 6, 10, 15, 34, 56]
seq_2 = [1, 2, 5, 7, 9, 18, 22, 38, 91]

# define a tuple
seq_3 = (1, 2, 3, 6, 10, 15, 34, 56)

# compare the sequences
# seq_1 vs seq_2
print(f"Is seq_1 is equal to seq_2: {seq_1 == seq_2}") # two sequences are obviously different.
print(f"Is seq_1 is greater than seq_2: {seq_1 > seq_2}") # third valus of seq_1 is not greater than seq_2.
print(f"Is seq_1 is less than seq_2: {seq_1 < seq_2}") # necause 3 is less than the 5.

# output
Is seq_1 is equal to seq_2: False
Is seq_1 is greater than seq_2: False
Is seq_1 is less than seq_2: True


# sequences that have equal values but different number of items.
seq_4 = [10, 20, 30]
seq_5 = [10, 20, 30, 40, 50]
print(f"Is seq_4 is less than seq_5: {seq_4 < seq_5}")

# output
Is seq_4 is less than seq_5: True

# Sequences must be of the same type to be compared
print(f"Is the same type of seq_1 and seq_3: {seq_1 == seq_3}") # that's different types.
print(f"Is the same type of seq_1 and seq_3: {tuple(seq_1) == seq_3}") # these are tuples.

# use the all() funtion to compare two arbitrary sequences
result = all(x == y for x, y in itertools.zip_longest(seq_1, seq_3))
print(result)

# output
Is the same type of seq_1 and seq_3: False
Is the same type of seq_1 and seq_3: True
True

 

import itertools

names = ["Joe", "Jane", "Jim"]

# cycle iterator can be used to cycle over a collection infinitely
cycler = itertools.cycle(names)
print(next(cycler))
print(next(cycler))
print(next(cycler))
print(next(cycler))

# output
Joe
Jane
Jim
Joe

#  use count to create a simple counter
counter = itertools.count(100, 10)
print(next(counter))
print(next(counter))
print(next(counter))

# output
100
110
120

# accumulate creates an iterator that accumulates values
vals = [10, 20, 30, 40, 50, 40, 30]
acc = itertools.accumulate(vals)
print(list(acc))

# output
[10, 30, 60, 100, 150, 190, 220] # it's running total.

# amortize a loan over a set number of payments for a 2000 loan at 4%
payments = [100, 125, 200, 105, 100, 120, 110, 130, 150, 100, 110, 120]
update = lambda balance, payment: round(balance * 1.04) - payment
balances = itertools.accumulate(payments, update, initial=2_000)
print(list(balances))

# output
[2000, 1980, 1934, 1811, 1778, 1749, 1699, 1657, 1593, 1507, 1467, 1416, 1353]

 

# Itertools: chain, chain.from_iterable

import itertools

# chain() creates a single iterable from multiple
chained = itertools.chain("abcd", "1234")
print(list(chained))

# output
['a', 'b', 'c', 'd', '1', '2', '3', '4']

# Using chain() for build a flat list
list_1 = [[1, 2, 3, 4], [5]]
list_2 = [6, 7]

flat_list = itertools.chain(list_1, list_2)
print(list(flat_list))

# output
[[1, 2, 3, 4], [5], 6, 7]

flat_list = itertools.chain(list_1, list_2)
flat_int = [inner for outer in flat_list for inner in (outer if isinstance(outer, list) else [outer])] # flatten
print(flat_int)

# output
[1, 2, 3, 4, 5, 6, 7]


# chain.from_iterable is an alternate usage of chain
s1 = "abcdefg"
s2 = [1, 2, 3, 4, 5]
s3 = ['$', '%', '@', '&']

result = itertools.chain.from_iterable([s1, s2, s3])
print(list(result))

# output
['a', 'b', 'c', 'd', 'e', 'f', 'g', 1, 2, 3, 4, 5, '$', '%', '@', '&']

 

# Itertools: dropwhile, takewhile, filterfalse
import itertools
import pprint
from dataclasses import dataclass

vals = [10, 20, 30, 40, 50, 40, 30, 25, 55, 45, 40, 30]

# dropwhile and takewhile will return values until
# a certain conditions is met that stops them.

def condition_func(n):
    return n < 40

# dropwhile() drops values until the predicate expression is True.
print(list(itertools.dropwhile(condition_func, vals)))

# takewhile() is the oppsite of dropwhile() - it returns values from
# the iterable while the predicate is True, then stops.
print(list(itertools.takewhile(condition_func, vals)))

# output
[40, 50, 40, 30, 25, 55, 45, 40, 30]
[10, 20, 30]


# filterfalse() returns elements from the iterable for which the predicate
# function returns False.
result = list(itertools.filterfalse(lambda x: x % 2 == 0, vals))
print(result)

# output
[25, 55, 45]

# These functions can work on complex objects.
@dataclass
class wcdata:
    game: str
    attendance: int
    team1: str
    team2: str
    score: str

world_cup_data = [
    wcdata("Final", 88966, "Argentina", "France", "3 (4) -- 3 (2)"),
    wcdata("3rd Place", 44137, "Croatia", "Moroco", "2 -- 1"),
    wcdata("Semi final", 68294, "France", "Moroco", "2 -- 0"),
    wcdata("Semi final", 88966, "Argentina", "Croatia", "3 -- 0"),
]

result = list(itertools.filterfalse(lambda x: x.attendance < 80_000, world_cup_data))
pprint.pp(result)

# output
[wcdata(game='Final',
        attendance=88966,
        team1='Argentina',
        team2='France',
        score='3 (4) -- 3 (2)'),
 wcdata(game='Semi final',
        attendance=88966,
        team1='Argentina',
        team2='Croatia',
        score='3 -- 0')]

 

# Itertools: combinations and permutatios

import itertools
import pprint

# product() produces the cartesian product of input iterables
cards = "A23456789TJQK" # cards of Ace to King.
suits = "SCHD"

deck = list(itertools.product(cards, suits))
print(len(deck), "cards")
pprint.pp(deck)

# output
52 cards
[('A', 'S'),
 ('A', 'C'),
 ('A', 'H'),
 ('A', 'D'),
 ('2', 'S'),
 ('2', 'C'),
 ('2', 'H'),
 ('2', 'D'),
 ('3', 'S'),
 ('3', 'C'),
 ('3', 'H'),
 ('3', 'D'),
 ('4', 'S'),
 ('4', 'C'),
 ('4', 'H'),
 ('4', 'D'),
 ('5', 'S'),
 ('5', 'C'),
 ('5', 'H'),
 ('5', 'D'),
 ('6', 'S'),
 ('6', 'C'),
 ('6', 'H'),
 ('6', 'D'),
 ('7', 'S'),
 ('7', 'C'),
 ('7', 'H'),
 ('7', 'D'),
 ('8', 'S'),
 ('8', 'C'),
 ('8', 'H'),
 ('8', 'D'),
 ('9', 'S'),
 ('9', 'C'),
 ('9', 'H'),
 ('9', 'D'),
 ('T', 'S'),
 ('T', 'C'),
 ('T', 'H'),
 ('T', 'D'),
 ('J', 'S'),
 ('J', 'C'),
 ('J', 'H'),
 ('J', 'D'),
 ('Q', 'S'),
 ('Q', 'C'),
 ('Q', 'H'),
 ('Q', 'D'),
 ('K', 'S'),
 ('K', 'C'),
 ('K', 'H'),
 ('K', 'D')]

# permutations() creates tuples of a given length with no repeated elements
# 4개의 팀이 있고 각각 홈 - 원정 두 번씩 경기를 치른다. (each of the permutations to have two elements.)
# 총 경기 조합은?
teams = ("A", "B", "C", "D")
result = list(itertools.permutations(teams, 2))
print(result)

# output
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C')]

# combinations() will create combinations of a given length with no repeats
result = list(itertools.combinations("ABCD", 3)) # using combinations, the order doesn't matter.
# A, B, C and C, B, A would be considered the same, so it only appears once.
print(result)

# output
[('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')]

# combinations_with_replacement() will create combinations of a given length with repeats.
result = list(itertools.combinations_with_replacement("ABCD", 3))
print(result)

# output
[('A', 'A', 'A'), ('A', 'A', 'B'), ('A', 'A', 'C'), ('A', 'A', 'D'), ('A', 'B', 'B'), ('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'C'), ('A', 'C', 'D'), ('A', 'D', 'D'), ('B', 'B', 'B'), ('B', 'B', 'C'), ('B', 'B', 'D'), ('B', 'C', 'C'), ('B', 'C', 'D'), ('B', 'D', 'D'), ('C', 'C', 'C'), ('C', 'C', 'D'), ('C', 'D', 'D'), ('D', 'D', 'D')]
반응형

관련글 더보기

댓글 영역