Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Python2 and Python3 while using map with find and index

Given a pattern and a string str, find if str follows the same pattern.

Here follows means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

Examples: pattern = "abba", str = "dog cat cat dog" should return true; dog is a, cat is b and the words form the abba pattern. pattern = "abba", str = "dog cat cat fish" should return false; the string follows a abbc pattern instead.

My solution works in Python 2:

def wordPattern(self, pattern, str):
    s = pattern
    t = str.split()
    return map(s.find, s) == map(t.index, t)

But I am just wondering why this solution does not working in Python 3. There, the function will always return False when trying to test the above examples. Could anyone please give some advice?

like image 674
user3651247 Avatar asked Feb 13 '18 13:02

user3651247


1 Answers

In Python 3, map() returns an iterator object, not a list. Equality testing between these objects won't work (equality is testing for identity, the exact same object in memory, instead).

Convert to lists explicitly:

def wordPattern(self, pattern, str):
    s = pattern
    t = str.split()
    return list(map(s.find, s)) == list(map(t.index, t))

or use list comprehensions:

def wordPattern(self, pattern, str):
    s = pattern
    t = str.split()
    return [s.find(c) for c in  s] == [t.index(w) for w in t]

or avoid creating lists altogether by comparing the zipped results with the all() function:

from operator import eq
from itertools import starmap, zip_longest

def wordPattern(self, pattern, str):
    s = pattern
    t = str.split()
    return all(starmap(eq, zip_longest(map(s.find, s), map(t.index, t))))

The latter short-circuits without having to make all comparisons if there is no match. In the spirit of keeping the functional style, I used itertools.starmap() to test for equality with the operator.eq() function. By using itertools.zip_longest() we make sure that we can detect the case where the pattern length and word count don't match.

like image 158
Martijn Pieters Avatar answered Oct 04 '22 00:10

Martijn Pieters