2015-11-06 87 views
1

我可以定义返回重复元素的索引列表中的一个功能:如何得到list元素是列表的重复元素的索引?

>>> 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' 
+0

您如何期望它能在清单列表上工作?我基本上可以看到三种方式。 (1)与以前一样在外部单独列表中工作,(2)与以前一样工作,但比较重复_列表_(如'[1,2]'出现两次),(3)像以前一样工作但仅适用于列表的嵌套列表(不适用于常规的整数列表)。 –

回答

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] 
0

列表对象不是哈希的,所以你不能把它们存储在一个set,你可以将它们转换为元组是哪个哈希的。

也为寻找重复项目使用更好的字典来保存在一个列表作为值的项目为重点和指数和指数更Python的方式。

>>> 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] 
+0

不确定这对OP是否有影响,但是将所有列表成员转换为'tuple'会将功能转换为其先前的域。也就是说,它不再适用于一个简单的整数列表。 –

+0

@ Two-BitAlchemist是的,我更新了答案。 – Kasramvd