我是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]输出。
答案 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
将返回None
而not None
为True
,因此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