【问题标题】:How can I make my code be a set?我怎样才能让我的代码成为一个集合?
【发布时间】:2012-10-04 21:15:03
【问题描述】:

我有一个小代码,它接受一个对象列表,并且只输出列表中唯一的项目。

这是我的代码

def only_once(a):
    return [x for x in a if a.count(x) is 1]

不过,我的老师要求我们为此功能使用集合。 谁能告诉我我能做什么?

我的代码必须接受 a=[1,4,6,7,3,2,4,5,7,5,6] 之类的输入,然后输出 [1, 3, 2]。也必须保持它的顺序。

【问题讨论】:

标签: python


【解决方案1】:

[我假设您也是 user1744238 和 user1744316 - 请选择一个用户名并坚持使用,这样可以更轻松地查看您提出的问题的变体以及您已经提出的问题试过了。]

一种基于集合的方法是使用两个集合作为计数器。你只关心你是否见过一次或不止一次。例如,这是一个易于解释的方法:

  1. oncemore 创建一个空集。
  2. 遍历列表的每个元素,然后:
    1. 如果您以前没有看过,请将其添加到once
    2. 如果您看过一次,请将其从once 中删除并添加到more
  3. 现在您知道在集合once 中您只看到过哪些元素。
  4. 循环遍历列表的元素,如果您看过一次,请将其添加到输出列表中,然后将其从 once 集中删除,这样您就不会输出相同的元素两次。

这给了我:

In [49]: f([1,4,6,7,3,2,4,5,7,5,6])
Out[49]: [1, 3, 2]

【讨论】:

  • 非常感谢,我同意 Blender。很有帮助,正在尝试使用此构建
  • 这基本上是我在帖子中使用的算法(是的,我忽略了这个的家庭作业方面),除了我不费心从“一次”中删除项目,因为你可以反转检查并使用“更多”。
  • @agf:是的,这是更好的方法。
【解决方案2】:

澄清一下,您想要的是一组出现一次且仅出现一次的项目。

这里最好的选择是使用collections.Counter(),因为这意味着您只计算项目一次,而不是每个项目一次,从而大大提高性能:

>>> import collections
>>> {key for key, count in collections.Counter(a).items() if count == 1}
{1, 2, 3}

我们只是用花括号代替方括号来表示集合推导而不是列表推导,以获得一组结果。

【讨论】:

  • 我已经有了一个方法,我只需要它是一个使用 set() 的方法
  • 确实,在 2.7 之前,您可以使用带有生成器表达式的 set() 构造函数。
  • 我认为使用 Counter 和集合推导会混淆算法,这对于初学者来说很重要。
【解决方案3】:

如果您需要多次删除列表中的任何项目,而不仅仅是第一个之后的出现,您可以使用:

# without using generators / comprehensions
def only_once(iterable):
    seen = set()
    duplicates = set()
    for item in iterable:
        if item in seen:
            duplicates.add(item)
        seen.add(item)
    result = []
    for item in iterable:
        if item not in duplicates:
            result.append(item)
    return result

对于一般的顺序保留重复消除,请参阅itertools recipes 中的unique_everseen

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in ifilterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

【讨论】:

  • +1,我查看了itertools,因为我确信这有一些东西,但没有看到这个。这里最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 2020-10-16
  • 2021-06-29
  • 2021-02-26
  • 2014-08-19
  • 1970-01-01
相关资源
最近更新 更多