2015-11-02 97 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] 
相关问题