【问题标题】:Python - Removing duplicates in list only by using filter and lambdaPython - 仅使用过滤器和 lambda 删除列表中的重复项
【发布时间】:2017-01-08 01:09:32
【问题描述】:

我需要在没有集合、函数或循环的情况下删除列表中的重复项 - 只能使用过滤器和 lambda 函数。

我的尝试是:

list(filter(lambda x: x in l[:].remove(x), l))

但 remove 返回已删除的项目而不是整个列表。有什么建议吗?

【问题讨论】:

  • 但是为什么不设置、函数和循环呢?你没说。
  • 这就是任务。这是我需要为作业构建的算法的一部分。
  • 你能举个例子吗?应该将 [1, 2, 2, 3] 转换为 [1, 2, 3] 还是要过滤掉所有条目并以 [1, 3] 结束?
  • 对于输入 [1, 2, 2, 3],我们将得到 [1, 2, 3]。
  • 我认为您的支票有误。 filter() 需要函数返回 True 以保留东西。所以你想要x not in 而不是x in

标签: python


【解决方案1】:

您需要以某种方式保持某种状态。如果您可以使用新列表,则可以执行以下操作:

g = l[:]
filter(lambda x: g.remove(x) is None and g.count(x) == 0, l)

以上内容以不同的方式删除重复项。如果你有l = [1, 2, 2, 3, 2],你最终会得到[1, 3, 2] 作为结果列表。

或者创建一个空列表并使用它来跟踪您所看到的:

seen = []
return filter(lambda x: seen.append(x) is None if x not in seen else False, l)

以上两种方法都非常类似于使用集合,但效率要低得多。 :-) 两者都使用了一种愚蠢的机制来允许在适当的位置改变列表,但返回 True/False 结果(两者中的is None 部分允许我们将表达式链接在一起)。

如果你可以使用mapenumerate,你可以这样做:

map(lambda t: t[1],
    filter(lambda t: l[:t[0]].count(t[1]) == 0, enumerate(l)))

(它使用当前索引查看列表的前一部分以查找重复项)

如果你可以使用列表推导,你可以去掉map

[x for i, x in filter(lambda t: l[:t[0]].count(t[1]) == 0,
                      enumerate(l))]

如果您可以使用reduce,那么您可以执行以下操作:

reduce(lambda r, x: r + [x] if x not in r else r, l, [])

因为您可以通过将结果从一个迭代传递到下一个迭代来保持状态。

但不知何故,您需要记录所见内容。这些都不是我所谓的优雅 Python 代码,除了 reduce 版本——尽管它不是高性能的。

【讨论】:

    【解决方案2】:

    我只使用lambda 函数做了一个解决方案。

    以下lambda 函数返回一个与作为参数传递的列表相对应的列表,没有重复:

    lambda l: (lambda u, a: u(u, a)) ((lambda f, x: x if len(x) <= 1 else (f(f, x[1:]) if x[0] in x[1:] else ([x[0]] + f(f, x[1:])))), l)
    

    由于目标有点不同,我发布了一个单独的 Q/A,我在这里解释一下:Removing duplicates using only lambda functions

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 2016-09-16
      • 1970-01-01
      • 2012-12-12
      • 2019-08-21
      • 2011-10-04
      • 2023-02-13
      相关资源
      最近更新 更多