如何获得列表重复元素的索引,其中元素是列表?

时间:2015-11-06 18:43:24

标签: python list recursion duplicates

我可以定义一个函数来返回列表中重复元素的索引:

>>> def indices_of_list_element_duplicates(x):
...     seen = set()
...     seen_add = seen.add
...     return [index for index, element in enumerate(x)\
...         if element in seen or seen_add(element)]
... 

此功能适用于简单列表:

>>> a = [1, 2, 3, 3, 4, 3]
>>> indices_of_list_element_duplicates(a)
[3, 5]

如何更改此功能以使其能够在列表中作为元素使用?

>>> b = [[1, 1], [2, 2], [3, "d"], [3, "d"], [4, 4], [3, "d"]]
>>> indices_of_list_element_duplicates(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in indices_of_list_element_duplicates
TypeError: unhashable type: 'list'

2 个答案:

答案 0 :(得分:0)

列表对象不可清除,因此您无法将它们存储在set中,您可以将它们转换为可清除的元组。

此外,作为查找重复项目的更加pythonic方式,您最好使用字典将项目作为键,将列表中的索引和索引保存为值。

>>> Counter_obj={}
>>> 
>>> for i,j in enumerate(map(tuple,b)):
...     Counter_obj.setdefault(j,[]).append(i)
... 
>>> Counter_obj
{(3, 'd'): [2, 3, 5], (4, 4): [4], (1, 1): [0], (2, 2): [1]}

然后你可以使用嵌套列表理解返回长度大于2的值(索引):

>>> [i for val in Counter_obj.values() for i in val if  len(val)>2]
[2, 3, 5]

如果你想在函数中使用它作为一种更通用的方法,你可以使用以下方法来包装这两种情况:

def indices_of_list_element_duplicates(x,Counter_obj={}):
     try:
        for i,j in enumerate(map(tuple,b)):
            Counter_obj.setdefault(j,[]).append(i)
     except TypeError:
        for i,j in enumerate(b):
            Counter_obj.setdefault(j,[]).append(i)
     return [i for val in Counter_obj.values() for i in val if len(val)>2]

答案 1 :(得分:0)

您可以使用以下生成器函数来生成重复元素的索引。请注意,这仍然适用于简单的整体列表,列表列表或两者。

>>> def index_of_list_element_duplicates(x):
...     seen = set()
...     for index, element in enumerate(x):
...         if isinstance(element, list):
...             element = tuple(element)
...         if element not in seen:
...             seen.add(element)
...         else:
...             yield index
... 
>>> b = [[1, 1], [2, 2], [3, 'd'], [3, 'd'], [4, 4], [3, 'd'], 4, 4]
>>> list(index_of_list_element_duplicates(b))
[3, 5, 7]