Efficiently combining, counting, and iterating

Scrivere codice Python efficiente

Logan Thomas

Scientific Software Technical Trainer, Enthought

Pokémon Overview

  • Trainers (collect Pokémon)

alt=”Ash Ketchum; one of the many characters (called trainers) in the Nintendo video game Pokémon”

Scrivere codice Python efficiente

Pokémon Overview

  • Pokémon (fictional animal characters)

alt=”Squirtle, Pikachu, Bulbasaur, and Charmander; a few of the many Pokémon that exist in the Nintendo video game”

Scrivere codice Python efficiente

Pokémon Overview

  • Pokédex (stores captured Pokémon)

alt=”Pokédex, a tool used by trainers to store captured Pokémon”

Scrivere codice Python efficiente

Pokémon Description

alt=”The Pokémon named Squirtle along with its accompanying metadata”

Scrivere codice Python efficiente

Pokémon Description

alt=”The Pokémon named Squirtle along with its accompanying metadata and the Name and Generation field highlighted”

Scrivere codice Python efficiente

Pokémon Description

alt=”The Pokémon named Squirtle along with its accompanying metadata and the Type and Legendary field highlighted”

Scrivere codice Python efficiente

Pokémon Description

alt=”The Pokémon named Squirtle along with its accompanying metadata and the Health Points, Attack, Defense, Special Attack, Special Defense, Speed, and Total fields highlighted”

Scrivere codice Python efficiente

Combining objects

names = ['Bulbasaur', 'Charmander', 'Squirtle']
hps = [45, 39, 44]
combined = []

for i,pokemon in enumerate(names):
    combined.append((pokemon, hps[i]))

print(combined)
[('Bulbasaur', 45), ('Charmander', 39), ('Squirtle', 44)]
Scrivere codice Python efficiente

Combining objects with zip

names = ['Bulbasaur', 'Charmander', 'Squirtle']
hps = [45, 39, 44]
combined_zip = zip(names, hps)

print(type(combined_zip))
<class 'zip'>
combined_zip_list = [*combined_zip]

print(combined_zip_list)
[('Bulbasaur', 45), ('Charmander', 39), ('Squirtle', 44)]
Scrivere codice Python efficiente

The collections module

  • Part of Python's Standard Library (built-in module)
  • Specialized container datatypes
    • Alternatives to general purpose dict, list, set, and tuple
  • Notable:
    • namedtuple: tuple subclasses with named fields
    • deque: list-like container with fast appends and pops
    • Counter: dict for counting hashable objects
    • OrderedDict: dict that retains order of entries
    • defaultdict: dict that calls a factory function to supply missing values
Scrivere codice Python efficiente

The collections module

  • Part of Python's Standard Library (built-in module)
  • Specialized container datatypes
    • Alternatives to general purpose dict, list, set, and tuple
  • Notable:
    • namedtuple: tuple subclasses with named fields
    • deque: list-like container with fast appends and pops
    • Counter: dict for counting hashable objects
    • OrderedDict: dict that retains order of entries
    • defaultdict: dict that calls a factory function to supply missing values
Scrivere codice Python efficiente

Counting with loop

# Each Pokémon's type (720 total)
poke_types = ['Grass', 'Dark', 'Fire', 'Fire', ...]

type_counts = {}
for poke_type in poke_types: if poke_type not in type_counts: type_counts[poke_type] = 1 else: type_counts[poke_type] += 1
print(type_counts)
{'Rock': 41, 'Dragon': 25, 'Ghost': 20, 'Ice': 23, 'Poison': 28, 'Grass': 64,
 'Flying': 2, 'Electric': 40, 'Fairy': 17, 'Steel': 21, 'Psychic': 46, 'Bug': 65,
 'Dark': 28, 'Fighting': 25, 'Ground': 30, 'Fire': 48,'Normal': 92, 'Water': 105}
Scrivere codice Python efficiente

collections.Counter()

# Each Pokémon's type (720 total)
poke_types = ['Grass', 'Dark', 'Fire', 'Fire', ...]

from collections import Counter
type_counts = Counter(poke_types)
print(type_counts)
Counter({'Water': 105, 'Normal': 92, 'Bug': 65, 'Grass': 64, 'Fire': 48,
         'Psychic': 46, 'Rock': 41, 'Electric': 40, 'Ground': 30,
         'Poison': 28, 'Dark': 28, 'Dragon': 25, 'Fighting': 25, 'Ice': 23,
         'Steel': 21, 'Ghost': 20, 'Fairy': 17, 'Flying': 2})
Scrivere codice Python efficiente

The itertools module

  • Part of Python's Standard Library (built-in module)
  • Functional tools for creating and using iterators
  • Notable:
    • Infinite iterators: count, cycle, repeat
    • Finite iterators: accumulate, chain, zip_longest, etc.
    • Combination generators: product, permutations, combinations
Scrivere codice Python efficiente

The itertools module

  • Part of Python's Standard Library (built-in module)
  • Functional tools for creating and using iterators
  • Notable:
    • Infinite iterators: count, cycle, repeat
    • Finite iterators: accumulate, chain, zip_longest, etc.
    • Combination generators: product, permutations, combinations
Scrivere codice Python efficiente

Combinations with loop

poke_types = ['Bug', 'Fire', 'Ghost', 'Grass', 'Water']

combos = [] for x in poke_types: for y in poke_types: if x == y: continue if ((x,y) not in combos) & ((y,x) not in combos): combos.append((x,y))
print(combos)
[('Bug', 'Fire'), ('Bug', 'Ghost'), ('Bug', 'Grass'), ('Bug', 'Water'),
 ('Fire', 'Ghost'), ('Fire', 'Grass'), ('Fire', 'Water'),
 ('Ghost', 'Grass'), ('Ghost', 'Water'), ('Grass', 'Water')]
Scrivere codice Python efficiente

itertools.combinations()

poke_types = ['Bug', 'Fire', 'Ghost', 'Grass', 'Water']

from itertools import combinations
combos_obj = combinations(poke_types, 2)
print(type(combos_obj))
<class 'itertools.combinations'>
combos = [*combos_obj]
print(combos)
[('Bug', 'Fire'), ('Bug', 'Ghost'), ('Bug', 'Grass'), ('Bug', 'Water'),
 ('Fire', 'Ghost'), ('Fire', 'Grass'), ('Fire', 'Water'),
 ('Ghost', 'Grass'), ('Ghost', 'Water'), ('Grass', 'Water')]
Scrivere codice Python efficiente

Let's practice!

Scrivere codice Python efficiente

Preparing Video For Download...