2013-08-20 55 views
2

給定一個長度爲N的數組a,這是一個整數列表,我想提取重複值,其中每個包含重複位置的值都有一個單獨的列表。在僞數學:從數組中提取重複值和位置的提取列表

If |M| > 1: 
    val -> M = { i | a[i] == val } 

例(N=11):

a = [0, 3, 1, 6, 8, 1, 3, 3, 2, 10, 10] 

應給予以下列表:

3 -> [1, 6, 7] 
1 -> [2, 5] 
10 -> [9, 10] 

我加入了python標記,因爲我目前在編程語言(numpy和scipy都可用),但我更關心如何去做的一般算法。不過,代碼示例很好。

一個想法,我還沒有充實:構建一個元組列表,將a的每個條目與它的索引(i, a[i])配對。將第二個條目作爲關鍵字對列表進行排序,然後檢查第二個條目相同的連續條目。

+0

可能重複:http://stackoverflow.com/questions/9835762/find-and-list-duplicates-in-python-list –

+0

@SlaterTyranus:不。再次閱讀問題,我需要重複列表_及其位置_。 – Markus

+0

這就像是從這個問題12個字符的變化。足夠接近,你應該能夠從那裏弄清楚。 –

回答

3

的想法是創建一個字典映射值,以它出現的位置的列表。

這可以使用setdefault以簡單的方式完成。這也可以使用defaultdict來完成。

>>> a = [0, 3, 1, 6, 8, 1, 3, 3, 2, 10, 10] 
>>> dup={} 
>>> for i,x in enumerate(a): 
...  dup.setdefault(x,[]).append(i) 
... 
>>> dup 
{0: [0], 1: [2, 5], 2: [8], 3: [1, 6, 7], 6: [3], 8: [4], 10: [9, 10]} 

然後,實際的重複可使用一套理解濾除只出現一次的元素中提取。

>>> {i:x for i,x in dup.iteritems() if len(x)>1} 
{1: [2, 5], 10: [9, 10], 3: [1, 6, 7]} 
+0

+1正確使用字典理解 –

+0

我接受你的答案,因爲集合理解似乎是更清晰的外觀解決方案。 – Markus

1

填充一個字典,其鍵是整數的值,其值是這些鍵的位置列表。然後通過該字典並刪除所有鍵/值對只有一個位置。你將被留下重複的人。

4

下面是一個使用Python字典(實際上是一個defaultdict,爲了方便)的實現

a = [0, 3, 1, 6, 8, 1, 3, 3, 2, 10, 10] 
from collections import defaultdict 
d = defaultdict(list) 

for k, item in enumerate(a): 
    d[item].append(k) 
finalD = {key : value for key, value in d.items() if len(value) > 1} # Filter dict for items that only occurred once. 

print(finalD)  
# {1: [2, 5], 10: [9, 10], 3: [1, 6, 7]} 
+0

那最後一行真的應該是一個字典理解 –

+0

@SlaterTyranus好主意。出於某種原因,我從不記得字典理解存在。 – Brionius