Python3.7 和 Python2.7 在使用 map 和 lambda 的问题

极客点儿
  • 16

下面是一段使用 split 分割字符串的代码,分别使用 Python2.7 和 Python3.7 执行

def mySplit(s, cut):

    data = [s] 

    for i in cut:
            
        t = []

        map(lambda x: t.extend(x.split(i)), data)

        data = t 

    return [i for i in data if i]

s = 'ab;cd|efg|hi,,jkl|mn\topq;rst,uvw\txyz'
print(mySplit(s, ',;|\t'))

运行结果:

Geek-Mac:Downloads zhangyi$ python2.7 Nice.py 
['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
Geek-Mac:Downloads zhangyi$ python3.7 Nice.py 
[]
Geek-Mac:Downloads zhangyi$

由运行结果可知, Python2.7 运行正常,但是换成 Python3.7 执行就出现了问题。

如果换成循环就正常执行,我想知道是哪里出了问题,是 map、lambda 还是其他的的问题,望大神指点,不吝指教,多谢!

def mySplit(s, cut):

    data = [s] 

    for i in cut:
            
        t = []
            
        for x in data:
            t.extend(x.split(i))

        data = t 

    return [i for i in data if i]

s = 'ab;cd|efg|hi,,jkl|mn\topq;rst,uvw\txyz'
print(mySplit(s, ',;|\t'))

运行结果:

Geek-Mac:Downloads zhangyi$ python3.7 Nice.py 
['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
Geek-Mac:Downloads zhangyi$ python2.7 Nice.py 
['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
Geek-Mac:Downloads zhangyi$
回复
阅读 2.7k
2 个回答
✓ 已被采纳

原因是 Python3 里面 map 函数的返回值不再是一个 list,而是一个 map 对象,是一个迭代器。

迭代器是惰性计算的,因此除非调用迭代器,否则 lambda 函数根本没有执行。你可以这样,把:

map(lambda x: t.extend(x.split(i)), data)

改成:

list(map(lambda x: t.extend(x.split(i)), data))

转为list时要获得所有元素,强制让迭代器执行。


其实你的需求,可以用 re.split 来做,这里就不展开了,有需要可以看看。

这得从 python3 里的 map 的改动说起,在 python3 里,map 不再返回 list,而是返回了一个迭代器。迭代器有个特点是,某个元素是在你进行迭代的时候计算的。所以,在你这种用法里,t.extend(x.split(i)) 根本没有执行,除非你改成

for _ in map(lambda x: t.extend(x.split(i)), data): pass

但这样使用 map 不又多此一举了么?

是的,在你的这个案例中,你不应该用 map 的,而应该用循环。


除此之外,还有一种比较便捷的方法,是使用 re 模块的 split 方法,但至于用法效率嘛,你可以自己探索一下

宣传栏