From 2193602838de5f6b642b9928c841784820518815 Mon Sep 17 00:00:00 2001 From: Mark Pilgrim Date: Wed, 15 Jul 2009 09:54:39 -0400 Subject: [PATCH] changed alphametics to use set() instead of set comprehensions, which neatly dovetails with my irrational reluctance to explain comprehensions --- advanced-iterators.html | 18 +++++++++--------- diveintopython3.org | 1 + examples/alphametics.py | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) mode change 100644 => 100755 examples/alphametics.py diff --git a/advanced-iterators.html b/advanced-iterators.html index 17a4770..f17b1e9 100755 --- a/advanced-iterators.html +++ b/advanced-iterators.html @@ -50,7 +50,7 @@ import itertools def solve(puzzle): words = re.findall('[A-Z]+', puzzle.upper()) - unique_characters = {c for c in ''.join(words)} + unique_characters = set(join(words)) assert len(unique_characters) <= 10 first_letters = {word[0] for word in words} n = len(first_letters) @@ -127,30 +127,30 @@ if __name__ == '__main__':

Finding the unique items in a sequence

-

Set comprehensions make it trivial to find the unique items in a sequence. [FIXME-not sure if I’m going to cover set comprehensions in an earlier chapter; if not, this is certainly an abrupt and inadequate introduction to the topic.] +

Sets make it trivial to find the unique items in a sequence.

 >>> a_list = ['a', 'c', 'b', 'a', 'd', 'b']
->>> {c for c in a_list}                      
+>>> set(a_list)                      
 {'a', 'c', 'b', 'd'}
 >>> a_string = 'EAST IS EAST'
->>> {c for c in a_string}                    
+>>> set(a_string)                    
 {'A', ' ', 'E', 'I', 'S', 'T'}
 >>> words = ['SEND', 'MORE', 'MONEY']
->>> ''.join(words)                           
+>>> ''.join(words)                   
 'SENDMOREMONEY'
->>> {c for c in ''.join(words)}              
+>>> set(''.join(words))              
 {'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
    -
  1. Given a list of several strings, a set comprehension with the identity function will return a set of unique strings from the list. This makes sense if you think of it like a for loop. Take the first item from the list, put it in the set. Second. Third. Fourth — wait, that’s in the set already, so it only gets listed once. Fifth. Sixth — again, a duplicate, so it only gets listed once. The end result? All the unique items in the original list, without any duplicates. The original list doesn’t even need to be sorted first. +
  2. Given a list of several strings, the set() function will return a set of unique strings from the list. This makes sense if you think of it like a for loop. Take the first item from the list, put it in the set. Second. Third. Fourth — wait, that’s in the set already, so it only gets listed once, because Python sets don’t allow duplicates. Fifth. Sixth — again, a duplicate, so it only gets listed once. The end result? All the unique items in the original list, without any duplicates. The original list doesn’t even need to be sorted first.
  3. The same technique works with strings, since a string is just a sequence of characters.
  4. Given a list of strings, ''.join(a_list) concatenates all the strings together into one. -
  5. So, given a list of strings, this set comprehension returns all the unique characters across all the strings, with no duplicates. +
  6. So, given a list of strings, this line of code returns all the unique characters across all the strings, with no duplicates.

The alphametics solver uses this technique to get a list of all the unique characters in the puzzle. -

unique_characters = {c for c in ''.join(words)}
+
unique_characters = set(''.join(words))

This list is later used to assign digits to characters as the solver iterates through the possible solutions. diff --git a/diveintopython3.org b/diveintopython3.org index 274626a..283cc02 100755 --- a/diveintopython3.org +++ b/diveintopython3.org @@ -7,6 +7,7 @@ * Closures & Generators * Classes & Iterators * TODO 2nd draft Advanced Iterators + SCHEDULED: <2009-07-15 Wed> * TODO 2nd draft Unit Testing * TODO 1st draft Advanced Unit Testing * TODO 2nd draft Refactoring diff --git a/examples/alphametics.py b/examples/alphametics.py old mode 100644 new mode 100755 index fbaae83..90840df --- a/examples/alphametics.py +++ b/examples/alphametics.py @@ -9,7 +9,7 @@ import itertools def solve(puzzle): words = re.findall('[A-Z]+', puzzle.upper()) - unique_characters = {c for c in ''.join(words)} + unique_characters = set(''.join(words)) assert len(unique_characters) <= 10 first_letters = {word[0] for word in words} n = len(first_letters)