是str.strip功能障碍

时间:2018-01-16 12:15:00

标签: python functional-programming strip

我有一个从字符串拆分操作构建的列表,我想将它输入到map()函数,然后从它们的尾部括号和空格中删除这些子字符串。 并从他们重建一个列表。

teststring=" (A) / (B) "
result = list(map(str.strip, teststring.split("/"), " ()"))

但是最后,我只是简单地剥离了子串,而“所有组合都经过测试”,正如文档所述。

我知道另一种方法可用于列表理解:

result = [substr.strip(' ()' for substr in teststring.split("/")]  

哪个有效..但我想知道为什么地图不能正常工作。

我在python 3.6.4上,在Windows64上安装了Anaconda 4.4。

附属问题;以下topic给出了一些查找函数源代码的指针。但我找不到地图的代码(通常是内置函数),所以我看不出它是否有错误...

5 个答案:

答案 0 :(得分:4)

带有3个参数的

map表现不像你想象的那样。 map的第三个参数是作为第一个参数提供的函数的参数。它被用作第二个迭代。

来自docs

  

map(function,iterable,...)返回一个应用函数的迭代器   到每个可迭代的项目,产生结果。如果有的话   传递可迭代的参数,函数必须采用那么多参数   并且并行地应用于所有迭代的项目。同   多个迭代,迭代器在最短迭代时停止   累。对于已经安排了功能输入的情况   参数元组,参见itertools.starmap()

换句话说:

map(str.strip, teststring.split('/'), ' ()') 等同于

[substr.strip(' ()' for substr in teststring.split('/')]。它远远等同于

[(substr_1.strip(), substr_2.strip()) for (substr_1, substr_2) in zip(teststring.split("/"), ' ()')]

看到区别?

答案 1 :(得分:3)

map与您使用它的方式不同。当您执行map(f, a, b)时,它会产生f(a[0], b[0]), f(a[1], b[1]), ...,而您使用它时会产生f(a[0], b), f(a[1], b), ...

要解决此问题,您可以使用列表推导(如问题中)或lambda(例如lambda string: string.strip(" ()")

答案 2 :(得分:3)

问题是你似乎认为map的最后一个参数作为参数传递给被映射的函数,而不是从文档中发生的事情:

  

map(func,* iterables) - >地图对象

     

创建一个迭代器,使用每个参数计算函数   迭代的。当最短的可迭代用尽时停止。

换句话说,list(map(f, [1,2,3], 'abc'))相当于:

[f(1,'a'), f(2, 'b'), f(3, 'c')]

这不是你想要的。您希望使用string.strip作为第二个参数部分应用 " ()",而是将" ()"作为另一个可迭代的参数。所以,直截了当的解决方案,使用辅助函数:

In [9]: def strip_stuff(s):
   ...:     return s.strip(" ()")
   ...:

In [10]: list(map(strip_stuff, teststring.split("/")))
Out[10]: ['A', 'B']

如果你需要灵活,你可以做一个因子功能:

In [12]: def make_strip(stuff):
    ...:     def strip(s):
    ...:         return s.strip(stuff)
    ...:     return strip
    ...:

In [13]: list(map(make_strip(" ()"), teststring.split("/")))
Out[13]: ['A', 'B']

In [14]: list(map(make_strip("()"), teststring.split("/")))
Out[14]: [' (A) ', ' (B) ']

In [15]: list(map(make_strip(" )"), teststring.split("/")))
Out[15]: ['(A', '(B']

In [16]: list(map(make_strip(" ("), teststring.split("/")))
Out[16]: ['A)', 'B)']

答案 3 :(得分:3)

您可以使用operator.methodcaller

list(map(operator.methodcaller('strip',' ()'),teststring.split("/")))

答案 4 :(得分:1)

使用lambda功能可以实现如下:

map(lambda s: s.strip(" ()"), teststring.split("/"))