为什么从列表中删除重复项会产生[无,无]输出?

时间:2015-09-19 04:26:18

标签: python

我是Python的新手,我无法理解为什么我使用值获得结果。

#Remove duplicate items from a list
def remove_duplicates(list):
    unique_list = []
    return [unique_list.append(item) for item in list if item not in unique_list]
print remove_duplicates([1,1,2,2]) -> result [None, None]

当我打印结果时,它显示以下内容:[无,无]

PS:我已经看过其他解决方案并且也知道列表(set(list))但是我试图理解为什么上面的整数结果会给出[None,None]输出。

3 个答案:

答案 0 :(得分:3)

虽然使用set is the proper way,但代码的问题(如注释所示)是您实际上没有从函数返回unique_list,而是返回列表推导的结果。< / p>

def remove_duplicates(my_list):
    unique_list = []
    do = [unique_list.append(item) for item in my_list if item not in unique_list]
    return unique_list  # Actually return the list!

print remove_duplicates([1,1,2,2]) -> result [1, 2]

在这里,我简单地创造了一个无用的一次性变量do,它只是“运行”理解。理解?

每次调用unique_list.append(item)时,这种理解都会存储一个值...而且该值是append方法的结果,即None!因此do等于[None, None]

但是,您的unique_list 实际上已正确填充,因此我们可以将其返回,现在您的功能正常运行。

当然,这不是列表理解的正常用法,而且非常奇怪。

答案 1 :(得分:1)

代码的问题是方法list.append返回None。您可以使用以下代码轻松测试:

myList=[1, 2, 3]
print myList.append(4)

因此,您的解决方案将是

def remove_duplicates(myList):
    alreadyIncluded = []
    return [item for item in myList if item not in alreadyIncluded and not alreadyIncluded.append(item)]
print remove_duplicates([1,1,2,2]) 

这个想法是你将从一个包含aldeady元素的空列表开始,你将遍历列表中的所有元素,包括它们在alreadyIncluded列表中。 not是必要的,因为append将返回Nonenot NoneTrue,因此if不会受到包含的影响。

您包含了附加结果的列表(始终为None),但您需要的是通过if测试的元素列表。

我希望它有所帮助。

答案 2 :(得分:1)

正如其他答案所解释的那样,您获取None值列表的原因是list.append返回None,并且您正在调用它列表理解。这意味着您需要在唯一值列表旁边构建一个充满None值的列表。

我想建议你放弃列表理解。因为您需要访问外部状态(到目前为止看到的唯一值列表),所以理解不能轻易地完成您想要的操作。常规for循环更合适:

def remove_duplicates(lst):
    unique_list = []
    for item in lst:
        if item not in unique_list:
            unique_list.append(item)
    return unique_list

然而,更多Pythonic方法是使用set来处理唯一项目,并使您的函数成为生成器:

def remove_duplicates(lst):
    uniques = set()
    for item in lst:
        if item not in unique_list:
            yield item
            uniques.add(item)

标准库中的itertools.ifilterfase功能可以帮助进一步改善这一功能,如recipe in the docs所示(您必须向下滚动一下才能找到具体配方):< / p>

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 filterfalse(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