2015-11-02 138 views
0

Python中有兩個列表。根據值在Python中對兩個列表進行分組

list1 = ['a','a','b','a','c','b','c','a','d','a','b'] 
list2 = ['1','2','21','12','1','32','11','12','21','3','31'] 

我必須將list1中的類似元素分組。 list2中的相應元素也應根據此分組。輸出應該是這樣的:

list1 = [['a','a','a','a','a'],['b','b','b'],['c','c'],['d']] 
list2 = [['1','2','12','12','3'],['21','32','31'],['1','11'],['21']] 

這樣做的最好方法是什麼?

+0

您是否必須在輸出列表中保留元素的順序? – soon

+0

有很多方法可以做到這一點。你有什麼困難與你的方式? –

回答

1

此代碼應該這樣做:

final_list1 = [] 
final_list2 = [] 

for distinct in sorted(list(set(list1))): 
    index = 0 
    distinct_list1 = [] 
    distinct_list2 = [] 
    for element in list1: 
     if element == distinct: 
      distinct_list1.append(element) 
      distinct_list2.append(list2[index]) 
     index += 1 
    final_list1.append(distinct_list1) 
    final_list2.append(distinct_list2) 

list1 = final_list1 
list2 = final_list2 

這會給你到底你要的輸出。如果你真的不關心輸出,可能有更好的方法,如@soon建議。

2

如果你不關心第一個列表元素的順序,你可以使用defaultdict

In [7]: from collections import defaultdict 

In [8]: from itertools import izip 

In [9]: res = defaultdict(list) 

In [10]: for k, v in izip(list1, list2): 
    ....:  res[k].append(v) 
    ....:  

In [11]: print(res) 
defaultdict(<type 'list'>, {'a': ['1', '2', '12', '12', '3'], 'c': ['1', '11'], 'b': ['21', '32', '31'], 'd': ['21']}) 

In [12]: res.items() 
Out[12]: 
[('a', ['1', '2', '12', '12', '3']), 
('c', ['1', '11']), 
('b', ['21', '32', '31']), 
('d', ['21'])] 
-1

第一種情況可以歸納使用itertools.groupby:

groups = list() 
for k, group in itertools.groupby(list1): 
    groups.append(list(group)) 

第二個同樣基於你的keyfunc。瞭解更多關於itertools.groupby

1

此代碼爲我工作:

groups = list(set(list1)) 
list1_tmp, list2_tmp = [], [] 
for char in groups: 
    list1_tmp.append([]) 
    list2_tmp.append([]) 

for i in range(len(list1)): 
    list1_tmp[groups.index(list1[i])].append(list1[i]) 
    list2_tmp[groups.index(list1[i])].append(list2[i]) 

list1 = list1_tmp 
list2 = list2_tmp 

輸出應該是有效的,以及任何其他類似的輸入。

1

這裏有一個(一種醜陋的)實現,會做的伎倆:

list1 = ['a','a','b','a','c','b','c','a','d','a','b'] 
list2 = ['1','2','21','12','1','32','11','12','21','3','31'] 

def transform(in_list, other_list): 
    if len(in_list) != len(other_list): 
     raise ValueError("Lists must have the sema length!") 
    out_list = list() 
    out_other_list = list() 
    for i, c in enumerate(in_list): 
     for inner_list, inner_other_list in zip(out_list, out_other_list): 
      if c in inner_list: 
       inner_list.append(c) 
       inner_other_list.append(other_list[i]) 
       break 
     else: 
      out_list.append([c]) 
      out_other_list.append([other_list[i]]) 
    return out_list, out_other_list 

print transform(list1, list2) 
1

雖然我個人很喜歡soon's answer,這一次成功地檢索所需輸出。

lst= sorted(zip(list1,list2),key=lambda x:x[0]) 

intList=[] 

initial=lst[0][0] 
count=0 

for index,value in enumerate(lst): 
    if value[0]==initial: 
     continue 
    else: 
     intList.append(lst[count:index]) 
     initial=value[0] 
     count=index 

finList1=[[a for a,b in innerList] for innerList in intList] 
finList2=[[b for a,b in innerList] for innerList in intList] 
相關問題