任务:
开发一个clean_list (list_to_clean)
函数,
它接受 1 个参数 - 任意长度的任意值(字符串、整数和 float )的列表,
并返回一个具有相同值但没有重复项的列表。这意味着,如果原始列表中存在多个实例中的值,则该值的第一个“实例”将保留在原处,而第二个、第三个等将被删除。
示例:
函数调用:clean_list([32, 32.1, 32.0, -32, 32, '32'])
返回:[32, 32.1, 32.0, -32, '32']
我的代码:
def clean_list(list_to_clean):
no_dubl_lst = [value for _, value in set((type(x), x) for x in list_to_clean)]
return no_dubl_lst
print(clean_list([32, 32.1, 32.0, -32, 32, '32']))
结果:
[32.1, 32, -32, 32.0, '32']
但是我怎样才能恢复原来的顺序呢?
最佳答案
这里有两个问题,因此为了回答的目的,我将列出两个问题。
尊重类型(你已经弄清楚了)
Removing duplicates in lists建议构建一个中间集合
作为最快的方法。如果一个元素等于当前元素,则认为该元素存在于集合中。
就您而言,您不仅需要值相等,还需要类型相等。
那么为什么不构造一个中间元组(value, type)
集呢?
unique_list = [v for v,t in {(v,type(v)) for v in orig_list}]
保留顺序
按照 Does Python have an ordered set? 使用“有序集”容器 。例如:
自 3.7(以及 CPython 3.6,其中这是一个实现细节)开始,常规
dict
保留插入顺序:unique_list = [v for v,t in dict.fromkeys((v,type(v)) for v in orig_list)]
对于所有版本(也出现在 3.6+ 中,因为它有附加方法),使用
collections.OrderedDict
:import collections unique_list = [v for v,t in collections.OrderedDict.fromkeys((v,type(v)) for v in orig_list)]
作为引用,与撰写本文时的其他答案相比,我的机器(3.7.4 win64)上的 timeit
结果:
In [24]: l=[random.choice((int,float,lambda v:str(int(v))))(random.random()*1000) for _ in range(100000)]
In [26]: timeit dict_fromkeys(l) #mine
38.6 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [34]: timeit ordereddict_fromkeys(l) #mine with OrderedDict
53.3 ms ± 233 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [25]: timeit build_with_filter(l) #Ch3steR's O(n)
48.7 ms ± 214 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [28]: timeit dict_with_none(l) #Patrick Artner's
46.8 ms ± 377 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [30]: timeit listcompr_side_effect(l) #CDJB's
55.5 ms ± 801 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
关于python - 从列表中删除重复项,但考虑元素的类型并保留顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59973428/