通过子列表的给定元素从列表中分离一组子列表

时间:2014-10-01 01:38:17

标签: python algorithm python-2.7

输入是:

 main_list = [['a','1','x'], ['b','2', 'm'], ['a', '23', 'm'], ['c', '34', 'x'], ['b', '11'], ['b', '32', 'y']]

最终结果应为:

 a_list = [['a','1','x'], ['a', '23', 'm']]
 b_list = [['b','2', 'm'], ['b', '32', 'y']]   <-- note that list ['b', '11'] has not been included as it has less elements.
 c_list = ['c', '34', 'x']

就个人而言,我做了类似的事情:

 a_list = [[p for p in item] for item in main_list if "a" in item[0]]
 b_list = [[p for p in item] for item in main_list if "b" in item[0] and len(item) > 2]
 c_list = [[p for p in item] for item in main_list if "c" in item[0]]

想知道是否有办法一次性提取所有三个列表,而不是步行main_list三次。

要扩展问题,如果没有给出任何元素,你会怎么做?但你的算法应该按照公共元素对子列表进行排序,比如说,给定位置。

干杯,

2 个答案:

答案 0 :(得分:1)

有时最好的方法是最简单的方法。列表理解是好的,但可能变得笨拙和难以理解。它们也不比同类循环快。您无法轻松将此转换为列表理解的原因是您需要附加到现有列表以将1个列表转换为3.您可以使用yield执行某些操作,但这又是相当的一点工作。

main_list = [['a','1','x'], ['b','2', 'm'], ['a', '23', 'm'], ['c', '34', 'x'], ['b', '11'], ['b', '32', 'y']]

a_list, b_list, c_list = [],[],[]

for item in main_list:
    if "a" in item[0]:
        a_list.append(item)
    elif "b" in item[0] and len(item) > 2:
        b_list.append(item)
    elif "c" in item[0]:
        c_list.append(item)

print a_list
print b_list
print c_list

输出:

[['a', '1', 'x'], ['a', '23', 'm']]
[['b', '2', 'm'], ['b', '32', 'y']]
[['c', '34', 'x']]

答案 1 :(得分:1)

groupby模块中的

itertools将获取您要查找的信息(以及更多信息):

In [31]: main_list = [['a','1','x'], ['b','2', 'm'], ['a', '23', 'm'], ['c', '34', 'x'], ['b', '11'], ['b', '32', 'y']]

In [32]: g = itertools.groupby(main_list, key=lambda x: (x[0], len(x)))

要查看该生成器中的内容,请运行:

In [33]: for x in g: print x[0], list(x[1])
('a', 3) [['a', '1', 'x']]
('b', 3) [['b', '2', 'm']]
('a', 3) [['a', '23', 'm']]
('c', 3) [['c', '34', 'x']]
('b', 2) [['b', '11']]
('b', 3) [['b', '32', 'y']]

如您所见,这会生成所有长度的信息。你只对长度= 3感兴趣。根据您实际使用发生器的方式,有多种方法可以丢弃其他长度。

例如,这会将生成器g中的信息提取到字典d中,并显示您要查找的结果:

In [65]: g = itertools.groupby(main_list, key=lambda x: (x[0], len(x)))

In [66]: d = collections.defaultdict(list)

In [67]: for x in g:
    if x[0][1]==3: d[x[0][0]].append(list(x[1])[0])
   ....:     

In [68]: d['a']
Out[68]: [['a', '1', 'x'], ['a', '23', 'm']]

In [69]: d['b']
Out[69]: [['b', '2', 'm'], ['b', '32', 'y']]

In [70]: d['c']
Out[70]: [['c', '34', 'x']]