使用带有find和index的map时Python2和Python3之间的区别

时间:2018-02-13 13:24:33

标签: python python-3.x map-function

给定一个模式和一个字符串str,找出str是否遵循相同的模式。

以下表示完全匹配,以便在str中的字母格式和非空字词之间存在双射。

实施例: pattern = "abba"str = "dog cat cat dog"应该返回true; dogacatb,单词构成abba模式。 pattern = "abba"str = "dog cat cat fish"应该返回false;字符串遵循abbc模式。

我的解决方案适用于Python 2:

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

但我只是想知道为什么这个解决方案在Python 3中不起作用。在尝试测试上面的例子时,该函数将始终返回False。有人可以请一些建议吗?

1 个答案:

答案 0 :(得分:7)

在Python 3中,libstdc++.so.6.0.22返回迭代器对象,而不是列表。这些对象之间的平等测试不起作用(相等是测试身份,而不是内存中完全相同的对象)。

明确转换为列表:

map()

或使用列表推导:

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

或通过将压缩结果与all() function比较来完全避免创建列表:

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]

后者短路,如果没有匹配则无需进行所有比较。本着保持功能风格的精神,我使用itertools.starmap()来测试与operator.eq() function的相等性。通过使用itertools.zip_longest(),我们确保可以检测到模式长度和字数不匹配的情况。