2016-07-19 107 views
0

我知道這與Efficient way to compare elements in 2 lists類似,但我基本上在這個問題上有一個擴展。比較兩個列表中元素的有效方法?

說我有兩個列表:

a = [1,2,4,1,0,3,2] 
b = [0,1,2,3,4] 

我想找出a指數,其中元素等於b每個元素。

例如,我希望b[1]的示例輸出告訴我,在[0,3]

數據幀輸出將是有用的,是這樣的:

b index_a 
    0  4 
    1  0 
    1  3 
    2  1 
    2  6 
    3  5 
    4  3 

我使用之前是:

b = pd.DataFrame(b) 
a = pd.DataFrame(a) 
pd.merge(b.reset_index(),a.reset_index(), 
     left_on=b.columns.tolist(), 
     right_on = a.columns.tolist(), 
     suffixes = ('_b','_a'))['index_b','index_a']] 

不過,我不能確定這是否是必要的,因爲這些都是名單。 (我在處理數據框時以前使用過這種方法)。

我正在做這個操作數千次與更大的列表,所以我想知道是否有一個更有效的方法。

此外,B只是list(range(X))其中在這種情況下X = 5

如果任何人有一些投入我不勝感激!

感謝

+1

我們可以假定'了'的所有元素將被包含在'B'? –

+1

呃,'b'沒用。真正的信息只是'N'。您可以創建一個從範圍爲'0..N-1'的值到'a'的索引的映射。而要建立這個映射,你只需循環「a」。請注意,'b'中值爲'x'的元素在索引'x'處(因爲'b = list(range(N))')。事實上,如果映射具有連續的整數作爲關鍵字,則列表列表就足夠了:'indices = [[] for _in b];對於我,枚舉(一):索引[x] .append(i)' – Bakuriu

+0

是的,抱歉,我應該提到這一點。 –

回答

1
import collections 
dd=collections.defaultdict(list) 
for i,x in enumerate(a): 
    dd[x].append(i) 

>>> sorted(dd.items()) 
[(0, [4]), (1, [0, 3]), (2, [1, 6]), (3, [5]), (4, [2])] 
1

如果你在這裏所示的B排序連續整數,然後桶排序最爲有效。 否則,你可以構造一個散列表,其中值b作爲鍵,並構造一個a列表作爲值。

2

一個非常簡單和有效的解決方法是在範圍0..N-1建立從所述值的映射到的a指數。映射可以是一個簡單的列表,這樣就結束了:

indices = [[] for _ in b] 
for i, x in enumerate(a): 
    indices[x].append(i) 

運行示例:

>>> a = [1,2,4,1,0,3,2] 
>>> b = [0,1,2,3,4] 
>>> indices = [[] for _ in b] 
>>> for i,x in enumerate(a): 
...  indices[x].append(i) 
... 
>>> indices[1] 
[0, 3] 

注意b[i] == i因此保持b列表很沒用。

+0

好的我明白了。我有一種感覺'b'可能沒用,但我不知道如何去做。如果我要擺脫'b',你介意提供一個例子嗎? –

+0

@GarrettMiller如果你提前不知道b的大小,我的回答是完美的。如果你這樣做,你可以初始化'indices = [[] for _ in range(length)]'這個答案效果最好。 –

+0

@GarrettMiller用'for_in range(N)'或'for_in [0] * N''替換''中的_'b' – Bakuriu

0

我不知道這是否是有效的滿足你的需求,但是這會工作:

from collections import defaultdict 

indexes = defaultdict(set) 

a = [1,2,4,1,0,3,2] 
b = [0,1,2,3,4] 

for i, x in enumerate(a): 
    indexes[x].add(i) 

for x in b: 
    print b, indexes.get(x) 
相關問題