简体   繁体   English

Python:基于项目对将列表分组

[英]Python: group a list basing on pairs of items

My program generates lists like this: 我的程序生成如下列表:

mydata = ["foo", "bar", "baz", "quux", "quid", "quo"]

And I know from other data that these can be grouped in couples (here a list of tuples, but can be changed to whatever): 从其他数据中我知道,这些可以成对分组(这里是元组列表,但可以更改为任何形式):

static_mapping = [("foo", "quo"), ("baz", "quux"), ("quid", "bar")]

There's no ordering in the couples. 夫妻俩没有订餐。

Now on to the problem: my program generates mydata and I need to group data by couple but keeping a separate list of non-matched items. 现在开始解决问题:我的程序生成mydata ,我需要将数据分组但是要保留不匹配项的单独列表。 The reason is that at any moment mydata may not contain all items that are part of the couples. 原因是,在任何时候, mydata可能都不会包含夫妇中的所有项目。

Expected results on such a hypothetical function: 此类假设功能的预期结果:

 mydata = ["foo", "bar", "quo", "baz"]
 couples, remainder = group_and_split(mydata, static_mapping)
 print(couples)
 [("foo", "quo")]
 print(remainder)
 ["bar", "baz"]

EDIT: Examples of what I've tried (but they stop at finding the coupling): 编辑:我尝试过的示例(但他们停止寻找耦合):

found_pairs = list()
for coupling in static_mapping:
    pairs = set(mydata).intersect(set(coupling))
    if not pairs or len(pairs) != 2:
        continue
    found_pairs.append(pairs)

I got stuck at finding a reliable way to get the reminder out. 我被困在寻找一种可靠的方式来发出提醒。

You may try this: 您可以尝试以下方法:

import copy

def group_and_split(mydata, static_mapping):
    remainder = copy.deepcopy(mydata)
    couples = []
    for couple in static_mapping:
        if couple[0] in mydata and couple[1] in mydata:
            remainder.remove(couple[0])
            remainder.remove(couple[1])
            couples.append(couple)
    return [couples, remainder]

Set gives you faster runtime if values are big, but takes memory, and deepcopy keeps the original data intact. 如果值很大,Set可以让您更快地运行,但是会占用内存,并且Deepcopy会保持原始数据完整。

One of the implementations of the hypothetical functions could be :- 假设功能的实现之一可能是:

from copy import deepcopy

def group_and_split(mydata, static_mapping):
        temp  = set(mydata)
        couples = []
        remainder = deepcopy(mydata)
        for value1,value2 in static_mapping:
                if value1 in temp and value2 in temp:
                        couples.append((value1,value2))
                        remainder.remove(value1)
                        remainder.remove(value2)
        return couples, remainder

Here you have how to do it with sets using symmetric_difference function: 在这里,您将如何使用symmetric_difference函数对sets进行操作:

>>> full =  ["foo", "quo", "baz", "quux", "quid", "bar", 'newone', 'anotherone']
>>> couples = [("foo", "quo"), ("baz", "quux"), ("quid", "bar")]

## now for the remainder. Note you have to flatten your couples:
>>> set(full).symmetric_difference([item for sublist in couples for item in sublist])
set(['anotherone', 'newone'])
>>> 

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

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