简体   繁体   English

如何根据元组包含的字符串对列表进行分组?

[英]How to group a list of tuples based on the strings they contain?

I have a sorted list of two-string tuples. 我有一个两串元组的排序列表。 I also have another list of 4 character strings that are in some of those tuples. 我还列出了其中一些元组中的4个字符串。 I would like to group from one of these 4 character strings to the next in the list. 我想从这4个字符串之一到列表中的下一个分组。 It is a bit hard to explain so I will demonstrate. 有点难以解释,所以我将演示。

original_list = [('1321', 01), ('MessageXZY', 02), ('DescriptionSKS', 03), ('S7_6', 04), ('S7_3', 05), ('0A3B', 06), ('MessageZYA', 07),
 ('DescriptionKAM', 08), ('9K44', 09), ('MessageYAL', 10),
 ('DescriptionAUS', 11), ('S7_2', 12)]

I have the terms 1321 , OA3B and 9K44 saved in another list. 我将术语1321OA3B9K44保存在另一个列表中。 I would like to group everything between (and including) these terms into a tuple, like so: 我想将这些术语之间(包括其中)的所有内容归为一个元组,如下所示:

grouped_list = [(('1321', 01), ('MessageXZY', 02), ('DescriptionSKS', 03), ('S7_6', 04), ('S7_3', 05)), (('0A3B', 06), ('MessageZYA', 07),
 ('DescriptionKAM', 08)), (('9K44', 09), ('MessageYAL', 10),
 ('DescriptionAUS', 11), ('S7_2', 12))]

If the list that contains my 4 character terms is called code and the list containing the tuples is called original_list , what code would I need to achieve this? 如果包含我的4个字符术语的列表称为代码 ,而包含元组的列表称为original_list ,我需要什么代码来实现呢?

Edit: This is where I have gotten up to: 编辑:这是我起床的地方:

grouped_list = []
for tuple in original_list:
    for string in tuple:
        if string in code:
            grouped_list = list(zip ##zip that tuple and all consecutive tuples until the next item in code

Coming from a Ruby background, I often felt the need to use something like Enumerable#slice_before in Python. 来自Ruby背景,我经常感到有必要在Python中使用类似Enumerable#slice_before东西。 It basically splits any iterable into chunks. 基本上,它将所有可迭代的对象拆分为多个块。 The slice is done before every element for which the predicate is true. 切片在谓词为真的每个元素之前完成。

Based on the Rubinius implementation , I ported the code to Python. 基于Rubinius实现 ,我将代码移植到Python。

def slice_before(iterable, predicate):
    chunk = None
    for elem in iter(iterable):
        if predicate(elem):
            if chunk:
                yield chunk
            chunk = [elem]
        else:
            if not chunk:
                chunk = []
            chunk.append(elem)
    if chunk:
        yield chunk

Here are a few examples: 这里有一些例子:

>>> list(slice_before(range(12), lambda i: i % 3 == 0))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
>>> list(slice_before('LetsTestSliceBefore', str.isupper))
[['L', 'e', 't', 's'], ['T', 'e', 's', 't'], ['S', 'l', 'i', 'c', 'e'], ['B', 'e', 'f', 'o', 'r', 'e']]

You just need to initialize your data. 您只需要初始化数据即可。 Note that code_list could be a set for faster lookup: 请注意, code_list可以设置为快速查找:

original_list = [('1321', '01'), ('MessageXZY', '02'), ('DescriptionSKS', '03'), ('S7_6', '04'), ('S7_3', '05'), ('0A3B', '06'), ('MessageZYA', '07'), ('DescriptionKAM', '08'), ('9K44', '09'), ('MessageYAL', '10'),
 ('DescriptionAUS', '11'), ('S7_2', '12')]

code_list = {'1321', '0A3B','9K44'}

The required code for your problem becomes a one-liner with slice_before : 您的问题所需的代码成为slice_before

print(list(slice_before(original_list, lambda x_y: x_y[0] in code_list)))
# [[('1321', '01'), ('MessageXZY', '02'), ('DescriptionSKS', '03'), ('S7_6', '04'), ('S7_3', '05')], [('0A3B', '06'), ('MessageZYA', '07'), ('DescriptionKAM', '08')], [('9K44', '09'), ('MessageYAL', '10'), ('DescriptionAUS', '11'), ('S7_2', '12')]]

I am assuming that you have list of codes with which you want to split on. 我假设您有要拆分的代码列表。 According to that see if this code works for you. 据此,看看此代码是否对您有用。

original_list = [('1321', '01'), ('MessageXZY', '02'), ('DescriptionSKS', '03'), ('S7_6', '04'), ('S7_3', '05'), ('0A3B', '06'), ('MessageZYA', '07'), ('DescriptionKAM', '08'), ('9K44', '09'), ('MessageYAL', '10'),
 ('DescriptionAUS', '11'), ('S7_2', '12')]

code_list = ['1321', '0A3B','9K44']


grouped_tuples = []
for entry in original_list:
    if entry[0] in code_list:
        new_tuple = []
        new_tuple.append(entry)
        for i in range(original_list.index(entry)+1, len(original_list)):
            if(original_list[i][0] not in code_list):
                new_tuple.append(original_list[i])
            else:
                break
        grouped_tuples.append(tuple(new_tuple))
print grouped_tuples

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

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