[Tutor] Need help combining elements of a list of lists

Jim jf_byrnes at comcast.net
Wed Jul 11 12:09:57 EDT 2018


On 07/10/2018 11:03 PM, Mats Wichmann wrote:
> On 07/10/2018 09:09 PM, Steven D'Aprano wrote:
>> On Tue, Jul 10, 2018 at 09:46:57PM -0500, Jim wrote:
>>
>>> Say I have a list like ltrs and I want to print out all the possible 3
>>> letter combinations. I want to combine letters from each inner list but
>>> not combine any letters within the inner list itself. So ACF and ADF
>>> would be ok but ABC would not.
>>>
>>> I can lay it out manually and see the pattern, I cannot figure out how
>>> to do it programically. Just in case this looks like homework it is not.
>>> It's a small test case I devised to try to figure it out so I can apply
>>> it to a bigger real world problem I am working on.
>>>
>>> ltrs = [['A', 'B'], ['C', 'D', 'E'], ['F', 'G', 'H', 'I']]
>>
>> If you know that there are just three sublists, then you can do this:
>>
>> for a in ltrs[0]:
>>      for b in ltrs[1]:
>>          for c in ltrs[2]:
>>              print(a + b + c)
>>
>> I trust that's easy enough to understand.
>>
>> But here's a more general technique, where you don't need to know up
>> front how many nested lists there are:
>>
>>
>> from itertools import product  # short for "Cartesian Product"
>> for s in product(*ltrs):
>>      print(''.join(s))
> 
> This is one of those cases where: if it's homework, getting the nested
> loops right is almost certainly the way to go.  If it isn't, then
> itertools (that is, "using an available library solution") is almost
> certainly the way to go :)
> 
> If the eventual case is not just "letters", and a list of combined lists
> is the eventual goal, then the concise stanza is:
> 
> prods = list(product(*ltrs))
> 
> print(prods) then gives you:
> 
> [('a', 'c', 'f'), ('a', 'c', 'g'), ('a', 'c', 'h'), ('a', 'c', 'i'),
> ('a', 'd', 'f'), ('a', 'd', 'g'), ('a', 'd', 'h'), ('a', 'd', 'i'),
> ('a', 'e', 'f'), ('a', 'e', 'g'), ('a', 'e', 'h'), ('a', 'e', 'i'),
> ('b', 'c', 'f'), ('b', 'c', 'g'), ('b', 'c', 'h'), ('b', 'c', 'i'),
> ('b', 'd', 'f'), ('b', 'd', 'g'), ('b', 'd', 'h'), ('b', 'd', 'i'),
> ('b', 'e', 'f'), ('b', 'e', 'g'), ('b', 'e', 'h'), ('b', 'e', 'i')]
> 
> if you want them concatenated, then of course join is the way to do that.
> 
> 
>

Steven & Mats thanks for your replies.

It is more that just letters. I was reading Al Sweigart's book Cracking 
Codes with Python. I got to the chapter on substitution cyphers and 
wondered if his program could solve the daily Crypto Quips in the 
newspaper. Turns out it did not do a very good job because the quips 
were to short.

It did produce a dictionary where the keys are the letters of the 
alphabet and the items are a list of possible letters to substitute. If 
a key has no possible letters it is ignored, if a key has only one 
possible letter it considered a solution and plugged into the cypher. 
the keys with multiple possible letters are ones I am interested in.

I know you cannot brute force a substitution cypher but maybe I could 
loop over and combine the possible substitution letters and crack it 
that way. That's why I made up the letter problem, I wanted to see how 
to do it on a simple data set before attempting much more complex one.

It looks like the library solution is the way for me to try.

Regards,  Jim







More information about the Tutor mailing list