2

Q:1] Why are the print statements (commented) resulting in print(mapped) to not print the set? If those lines

# print(list(word))  
# print(list(palindrome))

are not-commented out, then the output results in:

['N', 'u', 'r', 's', 'e', 's', 'r', 'u', 'n']
['n', 'u', 'r', 's', 'e', 's', 'r', 'u', 'N']
The zipped result is : set()
Sentence is palindrome.

Q:2] Why does N==n not fail? I was expecting it to fail in the for loop.

def palindrome(word):
    if ' ' in word:
       word = word.replace(' ', '')
    palindrome = reversed(word)
    # print(list(word))
    # print(list(palindrome))
    mapped = zip(word, palindrome)
    # converting values to print as set 
    mapped = set(mapped) 
    # printing resultant values  
    print("The zipped result is : ",end="") 
    print(mapped) 
    for letter, rev_letter in zip(word, palindrome):
        if letter != rev_letter:
            return 'Not Palindrome'
    return 'Palindrome'

# Driver program to test sentencePalindrome() 
s = "Nurses run"
if (palindrome(s)): 
    print ("Sentence is palindrome.")
else: 
    print ("Sentence is not palindrome.")

If these lines below are commented

# print(list(word))
# print(list(palindrome))

the result is: The zipped result is : {('u', 'u'), ('n', 'N'), ('s', 's'), ('N', 'n'), ('e', 'e'), ('r', 'r')}
Sentence is palindrome.

RSSregex
  • 179
  • 7

1 Answers1

1

generators & containers

A generator resembles a sequence, as both are iterable. But a generator offers its values just once, while a container can be interrogated repeatedly.

You're getting hung up on that distinction, and the trouble started in this line:

    palindrome = reversed(word)

You are thinking of it as, "Oh, I have a word I can view, and each time I view it, it will be the same." No. Sorry. When you see it reported as something like:

<reversed object at 0x108ff7860>

you should think "generator" instead.

Q1. After print(list(palindrome)), why is mapped the empty set?

Because list() exhausted the generator. By the time zip() asked for the elements, all of them were already consumed.

Q2. Why does the for loop never encounter ('N', 'n') ?

Same answer. The 2nd zip obtains zero items, as the 1st zip already drained them.

I can see why this "crazy" behavior may lead you to some confusion, and a third question may already be on your lips:

Q3. Why is reversed() lazy, why doesn't it just compute and store the whole result?

Well, in python-land, laziness is a virtue. Consider this bit of code:

rev = reversed(very_long_sentence)
is_shouting = rev.startswith('!!')

Now startswith() only has to do a pair of character comparisons. And reversed() doesn't even have to examine the entire very long string, it can terminate early. Allowing early termination is a Good Thing. It can even let us operate on infinite generators, knowing full well that due to a termination clause we won't ask for all possible values.

fixing the bug

In your case, for this particular bit of code, you plan to view the reversed word several times. To handle that, a container is a much better fit for your needs. Fortunately, it's simple to store all the generated items:

palindrome = ''.join(reversed(word))

This way, instead of a generator, you have a str.

Community
  • 1
  • 1
J_H
  • 17,926
  • 4
  • 24
  • 44
  • I added the following print statements in the for loop. `print(letter)print(rev_letter)`. For `s=Nurses run`, only N and n were printed. When I tried `s=madam`, all characters were printer. Why? – RSSregex Apr 16 '19 at 04:15
  • You say you tried it twice: (1.) first and last letters were non-identical N/n, and (2.) first and last letters were identical m/m. You decided your function should offer an early exit for the first non-identical pair, returning a 'no' value. IDK, you tell me, why might the `print()` statements not have any effect subsequent to execution of a `return` statement? – J_H Apr 16 '19 at 04:24
  • word = word.replace(' ', '').lower() resolved the issue. – RSSregex Apr 16 '19 at 04:44