1

我遇到了一个问题,我必须从这样的列表中过滤掉骗子

a = [1,1,4,5,6,5]

这是我的代码:

def unique(a):
    uni = []
    for value in a:
        if value[0] not in found:
            yield value
            found.add(value[0])
            print list(unique(a))

但是,当我定义列表、a和 tryunique(a)时,我得到以下输出:

<generator object unique at 0x0000000002891750>

有人可以告诉我我做错了什么吗?为什么我拿不到名单?

编辑,新问题..我能够让它打印出过滤后的列表,但我失去了列表的顺序。我怎样才能防止这种情况?

def unique(a):
        s = set()
        for i in a:
            if i not in s:
                s.add(i)
        return s
4

4 回答 4

4

您必须跟踪已看到的所有元素。最好的方法是使用set它的查找复杂度为O(1).

>>> def unique(it):
        s = set()
        for el in it:
            if el not in s:
                s.add(el)
                yield el


>>> list(unique(a))
[1, 4, 5, 6]

如果您不需要保持元素的顺序,您可以使用set构造函数,然后将其转换回列表。这将删除所有重复项,但会破坏元素的顺序:

list(set(a))
于 2012-10-13T23:30:59.943 回答
3

首先,要删除重复项,请使用一组:

>>> a = [1, 1, 4, 5, 6, 5]
>>> set(a)
{1, 4, 5, 6}
>>> list(set(a)) # if you really _need_ a list, you can convert it back
[1, 4, 5, 6]

其次,你得到的输出generator object unique at 0x...,意味着你有一个生成器对象,而不是一个简单的列表作为它的返回值。这是你yield在函数中使用后应该期待的。yield如果您请求它们(或迭代它),将使任何函数成为生成器,并且只会给您所有结果。如果您只想获得完整的结果,您可以调用list()该对象以从生成器对象创建一个列表:list(unique(a)).

但是,你会注意到你的函数给你的错误:TypeError: 'int' object is not subscriptable. 原因是value[0]你使用的。value是列表中的一个元素(您遍历列表),因此是一个整数。您无法从整数中获取第一个元素,因此您可能意味着就value在那里。

接下来,found尽管您将列表定义为uni第一个,但您仍要向其中添加元素,因此您应该确定其中的一个名称。此外,方法是append,不是add

最后,你真的不应该在函数内部多次递归调用具有相同参数的方法,因为这只会填满堆栈而没有任何用处,所以删除它的打印。

然后,你最终得到了这个,它工作得很好:

>>> def unique(a):
        found = [] # better: use a set() here
        for value in a:
            if value not in found:
                yield value
                found.append(value)
>>> list(unique(a))
[1, 4, 5, 6]

但是,这仍然不是一个很好的解决方案,您应该直接使用set它,因为它还会为您提供更多方法来处理该集合一旦创建(例如快速检查包含性)。

我也需要通过输入得到答案unique(a)

在这种情况下,只需yield value从你的函数中删除,并found在它的末尾返回列表。

于 2012-10-13T23:36:53.633 回答
2

这是一个众所周知的经典:

>>> def unique(xs):
...     seen = set()
...     seen_add = seen.add
...     return [x for x in xs if x not in seen and not seen_add(x)]
...
>>> unique([1, 2, 3, 3, 4, 1, 3, 5, 5, 4, 6])
[1, 2, 3, 4, 5, 6]
于 2012-10-14T00:31:55.980 回答
0

通常的方法是list(set(a)

def unique(a):
  return list(set(a))

现在,来回答你的问题。yield返回一个生成器,您必须对其进行迭代而不是打印。所以如果你有一个函数,其中有一个yield,像这样迭代for return_value from function_that_yields():

你的问题还有更多问题。您尚未定义found,然后您索引可能不是容器的值。

于 2012-10-13T23:27:25.590 回答