简体   繁体   English

用子列表的给定元素将列表中的子列表集分开

[英]Separate a set of sublists from within a list by a given element of a sublist

Input is: 输入为:

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

Final result should be: 最终结果应为:

 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']

Personally, I did something like this: 我个人做了这样的事情:

 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]]

Wondering if there is a way to extract all three lists at once instead of walking main_list three times. 想知道是否有一种方法可以一次提取所有三个列表,而不是遍历main_list三次。

To extend the problem, how would you do it if no element is given but your algorithm should sort the sublists by common elements at, let's say, a given position. 为了扩展该问题,如果没有给出任何元素,但是算法应该按给定位置处的常用元素对子列表进行排序,您将如何处理。

Cheers, 干杯,

Sometimes the best way is the simplest way. 有时最好的方法是最简单的方法。 List comprehensions are good, but can get unwieldy and unreadable. 列表理解能力很好,但是可能难以理解且难以理解。 They are also no faster than a comparable for loop. 它们也不比可比的for循环快。 The reason you can't convert this into a list comprehension easily is that you will need to append to existing lists to convert 1 list into 3. You might be able to do something using yield but that again is quite a bit of work. 无法将其轻松转换为列表理解的原因是,您将需要追加到现有列表以将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

Outputs: 输出:

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

groupby in the itertools module will get the information you are looking for (and more): itertools模块中的groupby将获得您正在寻找的信息(以及更多信息):

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)))

To see what is in that generator, run: 要查看该生成器中的内容,请运行:

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']]

As you can see, this produces information for all lengths. 如您所见,这将生成所有长度的信息。 You are only interested in length=3. 您只对length = 3感兴趣。 Depending on how you actually want to use the generator, there are a variety of ways to throw away the other lengths. 根据实际使用生成器的方式,有多种方法可以丢弃其他长度。

As an example, this extracts the information from the generator g into a dictionary d with the results that you were looking for: 例如,此操作将生成器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']]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM