【问题标题】:lambda and filter in pythonpython中的lambda和过滤器
【发布时间】:2017-10-30 11:53:26
【问题描述】:

我有以下字符串,我想通过过滤 X 来解码

garbled = "IXXX aXXmX aXXXnXoXXXXXtXhXeXXXXrX sXXXXeXcXXXrXeXt mXXeXsXXXsXaXXXXXXgXeX!XX"

我想过滤。我尝试了以下代码

message = filter(lambda x: garbled.remove(x) if x == "X", garbled)

我没有让这种方式工作。我找到了另一个解决方案:

message = filter(lambda x: x != "X", garbled)

但我仍然想知道为什么第一个没有工作。我可以解决它吗?

(顺便说一句,我是 python 新手)谢谢!

【问题讨论】:

  • 所以你只想删除所有'X's?
  • 字符串没有任何remove 方法,因为字符串是不可变的。您的第一次尝试没有成功,因为它试图调用一个不存在的方法。
  • 为什么不只是decoded = garbled.replace('X', '')
  • 如果你想保留"X"会怎样?
  • 由于您是 Python 新手,您现在确实应该使用 Python 3...所有证据都表明您正在使用 Python 2...

标签: python lambda filter


【解决方案1】:

您可以使用生成器表达式代替filter

>>> ''.join(i for i in garbled if i != 'X')
'I am another secret message!'

如果您想使用 filter,您必须将您的 lambda 更改为

>>> ''.join(filter(lambda x: x != 'X', garbled))
'I am another secret message!'

【讨论】:

  • 仅供参考,joins 使用列表更有效,即''.join([i for i in garbled if i != 'X']),但我现在找不到帖子。
  • @timgeb 是的,但大多数情况下差异太小而无法注意到(尤其是与原始问题一样小的字符串)。除非性能成为问题,否则视觉上的混乱可能不值得。
【解决方案2】:

filter(function, iterable) 执行以下过程:

  1. 一次一个地遍历iterable(即第二个参数)中的元素。
  2. 对于这些元素中的每一个,在该元素上调用function(即第二个参数)并查看它是否返回true。
  3. 仅将 function 返回 true 的元素收集在一起,并返回这些元素的新列表。

如果您将lambda x: garbled.remove(x) if x == "X" 传递给function 参数,看看第2 步会发生什么:filter() 对自己说:“嗯,如果我设置了x="I",那么garbled.remove(x) if x == "X" 是真的吗?”。这就像你在第二个参数中对filter() 喊一个指令:“嘿,请删除所有"X"s”。但这不是去那里的正确选择。要求非常精确:它必须是一个接受元素并返回真或假值的函数。

【讨论】:

    【解决方案3】:

    Cory 已经修复了你的 filter

    在我看来,您的问题最好由简单的str.replace 处理。

    >>> garbled = "IXXX aXXmX aXXXnXoXXXXXtXhXeXXXXrX sXXXXeXcXXXrXeXt mXXeXsXXXsXaXXXXXXgXeX!XX"
    >>> garbled.replace('X', '')
    'I am another secret message!'
    

    【讨论】:

      【解决方案4】:
      message = filter(lambda x: garbled.remove(x) if x == "X", garbled)
      

      此代码不起作用,因为 lambda 函数必须是表达式。

      garbled.remove(x) if x == "X"
      

      这是语句,而不是表达式。 我删除 if x=="X" 来做一个有效的表达式,

      message = filter(lambda x: garbled.remove(x), garbled)
      

      接下来,我发现错误“'str' object has no attribute 'remove'”。 因为乱码的类型是字符串,并且字符串类型中没有名为'remove'的属性。 要使用过滤器函数,第一个参数必须是“谓词”函数(返回 True 或 False),第二个参数必须是可迭代的。 OP 的第二个解决方案满足这个条件。第二个参数是可迭代的字符串(字符列表),第一个参数是一个谓词函数,它接受从第二个参数字符串提供的一个字符)

      【讨论】:

      • 感谢优雅的解释 remove() 不能用于字符串类型。
      【解决方案5】:

      你可以这样做。你在 lambda 条件下有一个错误。你甚至不需要string.replace()

      garbled = "IXXX aXXmX aXXXnXoXXXXXtXhXeXXXXrX sXXXXeXcXXXrXeXt mXXeXsXXXsXaXXXXXXgXeX!XX"
      f = lambda x: "" if x in "X" else x
      message = filter(f, garbled)
      "".join(message)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-01
        • 1970-01-01
        相关资源
        最近更新 更多