-1

I would like to create a set of identities using all combinations of three uppercase letters while avoiding for loops to save computation time. I would like to have identities that range from ID_AAA to ID_ZZZ.

I can do this using for loops:

> from string import ascii_uppercase 
> IDs = [] 
>  for id_first_letter in ascii_uppercase:   
>    for id_second_letter in ascii_uppercase:
>      for id_third_letter in ascii_uppercase:
>        IDs.append('ID_' + id_first_letter + id_second_letter + id_third_letter)

But of course I would like to simplify the code here. I have tried to use the map function but the best I could come up with was this:

> from string import ascii_uppercase
> IDs = list(map(lambda x,y,z: 'ID_' + x + y + z,ascii_uppercase,ascii_uppercase,ascii_uppercase))

This is iterating among all letters at the same time, so I can only get ID_AAA, ID_BBB, ..., ID_ZZZ. All three letters are always the same as a consequence. Can I fine-tune this approach in order to iterate one letter at a time or do I need to use a totally different approach?

  • 1
    You say you want to simplify your code, but your code already ***is*** really simple. Maybe the simplest. Why do you think avoiding loops will make it simpler? – Kelly Bundy Feb 06 '23 at 15:15
  • @KellyBundy Thank you! Yet I was really convinced that the use of the for loops was the least computationally efficient way to do this and I was convinced I could do this using the map function or in some other way that could run faster. It turns out that I cannot avoid the loops in any case, even with the itertools module. – BrunoCAfonso Feb 06 '23 at 15:39
  • Your code takes like 5 milliseconds. Is that too slow? For what? – Kelly Bundy Feb 06 '23 at 15:55

3 Answers3

2

You are just reimplementing itertools.product.

from itertools import product
from string import ascii_uppercase 


IDs = [''.join(["ID_", *t]) for t in product(ascii_uppercase, repeat=3)]

or

IDs = [f'ID_{x}{y}{z}' for x, y, z in product(ascii_uppercase, repeat=3)]

depending on your preference for constructing a string from a trio produced by product.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

"Can I fine-tune this approach in order to iterate one letter at a time or do I need to use a totally different approach?" Yes...it will be 3 independent loops. It doesn't matter if you use map, loops or comprehensions, it's syntactic sugar in this case, you have to go through all the possibilities in this case, no shortcuts imho.

You can use e.g. product from itertools to make it more readable though:

from itertools import product
from string import ascii_uppercase 
IDs= []
for a,b,c in product(ascii_uppercase, repeat=3):
    IDs.append(f'ID_{a}{b}{c}')
Gameplay
  • 1,142
  • 1
  • 4
  • 16
1

You are essentially doing this:

>>> [f'ID_{x}{y}{z}' for x in ascii_uppercase for y in ascii_uppercase for z in ascii_uppercase]
['ID_AAA', 'ID_AAB', 'ID_AAC', ... 'ID_ZZX', 'ID_ZZY', 'ID_ZZZ']

Which is otherwise known as a Cartesian Product.

You can also just use product from itertools:

>>> from itertools import product
>>> [f'ID_{x}{y}{z}' for x,y,z in product(ascii_uppercase, repeat=3)]
['ID_AAA', 'ID_AAB', 'ID_AAC', ... 'ID_ZZX', 'ID_ZZY', 'ID_ZZZ']

And don't forget that it is better to refactor your code so that you don't generate the entire list if it is not necessary.

You can do this:

>>> ids_gen=(f'ID_{x}{y}{z}' for x in ascii_uppercase for y in ascii_uppercase for z in ascii_uppercase)
>>> next(ids_gen)
'ID_AAA' # and so on until exhausted...

or this:

>>> ids_gen=(f'ID_{x}{y}{z}' for x,y,z in product(ascii_uppercase, repeat=3))
>>> next(ids_gen)
'ID_AAA'

to generate one at a time.

(From comments, you can also do this generator:

from itertools import product, starmap
ids_gen=starmap("ID_{}{}{}".format, product(ascii_uppercase, repeat=3))

which is pretty cool...)

dawg
  • 98,345
  • 23
  • 131
  • 206
  • 2
    One more iterator: `starmap("ID_{}{}{}".format, product(ascii_uppercase, repeat=3))` – Kelly Bundy Feb 06 '23 at 15:20
  • 1
    Question is closed, could you include one more? Looks fast. In function `Kelly` here: – Kelly Bundy Feb 06 '23 at 16:26
  • 1
    https://ato.pxeger.com/run?1=lVRLTsMwFFywyyme2CShpmqLkFCl7tggjlBVVkjs1iixI-dFkFY9CRs2cCiuwQXwp4loGhDsLM94Zt57tl_eywY3Sr6-vtXIL28-zj65VgUIZBqVyisQRak0QqlVVqcYOLRCLeS6hZIqFYLWZcl0mlQMPAdFwQS2HM1KlmAQZIyD0mItZJJH8TwAuLutYAHLFZg1VxpERrnQFdKcoQkBQvYN5gCW3NErliqZ_cJ35I6OG6H_wHbJxonZllkU3t3SEEYn4Uan_qO-R2wENcNaS6voW3DP8rzx9XcdcB6rrjBqs-lErll0FR-FsmSRGSOv30HwvUx72toNgD-W7s37WdMNKyXT0zbuAV-G4fhRCRktz03wcwIXuIqdPlrpw32JehbkcBMWV_HqSH7Wl-e2H7vn_a7Z77b70Ck_E2gIbP-lnyVP65Psg-IDHXFA8xOwHexhwGuZ2iG195z4cZOuk91qRnw8c2Zo4naT202n6CtAI1yYrvsyI05A1sUD04vpJI4dozRv0wDhDuECppMJzK_HM76HooKQAB9TKpOCUWrZnhv7t3_4Atqv4As – Kelly Bundy Feb 06 '23 at 16:26