python-3.x 从具有不可哈希元素的列表中取出唯一值[duplicate]

h9vpoimq  于 2023-02-26  发布在  Python
关注(0)|答案(5)|浏览(76)

此问题在此处已有答案

Python, TypeError: unhashable type: 'list'(1个答案)
三年前关闭了。
所以我有以下列表:

test_list = ['Hallo', 42, [1, 2], 42, 3 + 2j, 'Hallo', 'Hello', [1, 2], [2, 3], 3 + 2j, 42]

现在我想从列表中取出唯一值并将其打印在屏幕上。我尝试使用set函数,但不起作用**(类型错误:不可用类型:'list')**,因为列表中的值是[1,2]和[2,3]。我尝试使用append和extend函数,但还没有找到解决方案。
期望值:[“你好”,42,[1,2],(3+2j),“你好”,[2,3]]

def unique_list(a_list): 
    a = set(a_list)
    print(a)
a_list = ['Hallo', 42, [1, 2], 42, 3 + 2j, 'Hallo', 'Hello', [1, 2], [2, 3], 3 + 2j, 42]
print(unique_list(a_list))
watbbzwu

watbbzwu1#

如果列表包含不可散列的元素,请使用repr创建一个可用于set的可散列键:

def unique_list(a_list):
    seen = set()
    for x in a_list:
        key = repr(x)
        if key not in seen:
            seen.add(key)
            print(x)
toe95027

toe950272#

你可以使用一个简单的for循环,它只追加新元素:

test_list = ['Hallo', 42, [1, 2], 42, 3 + 2j, 'Hallo', 'Hello', [1, 2], [2, 3], 3 + 2j, 42]
new_list = []

for item in test_list:
    if item not in new_list:
        new_list.append(item)

print(new_list)
# ['Hallo', 42, [1, 2], (3+2j), 'Hello', [2, 3]]
dpiehjr4

dpiehjr43#

为了从非散列列表中获取唯一项,可以通过等价性进行分区,这是一种二次方法,因为它将每个项与每个分区中的一个项进行比较,如果不等于其中一个项,则只为该项创建一个新分区,然后获取每个分区的第一个项。
如果某些项是可散列的,那么可以将等价性的划分限制在非散列项上,并通过集合来填充其余项。

import itertools

def partition(L):
    parts = []
    for item in L:
        for part in parts:
            if item == part[0]:
               part.append(item)
               break
        else:
            parts.append([item])
    return parts

def unique(L):
    return [p[0] for p in partition(L)]

未经测试。

f45qwnt8

f45qwnt84#

在线性时间内解决这个问题的一种方法是用序列化器(如pickle)序列化项,这样列表等不可散列的对象就可以添加到集合中进行重复数据删除,但是由于集合在Python中是无序的,而且你显然希望输出是按照原始插入顺序的,所以你可以改用dict.fromkeys

import pickle
list(map(pickle.loads, dict.fromkeys(map(pickle.dumps, test_list))))

因此,给定示例输入,它将返回:

['Hallo', 42, [1, 2], (3+2j), 'Hello', [2, 3]]

请注意,如果您使用的是Python 3.6或更早版本,其中dicts的键顺序不受保证,则可以使用collections.OrderedDict代替dict

b1payxdu

b1payxdu5#

你可以在一个普通的for循环中完成,这个循环的运行时间是O(n^2)。

def unique_list(a_list):
    orig = a_list[:]               # shallow-copy original list to avoid modifying it
    uniq = []                      # start with an empty list as our result
    while(len(orig) > 0):          # iterate through the original list
        uniq.append(orig[0])       # for each element, append it to the unique elements list
        while(uniq[-1] in orig):   # then, remove all occurrences of that element in the original list
            orig.remove(uniq[-1])
    return uniq                    # finally, return the list of unique elements in order of first occurrence in the original list

也许还有一种方法可以把它变成列表解析,那会更优雅,但是我现在还不知道,如果每个元素都是可散列的,你可以使用set方法,那会更简单。

相关问题