如何在Python中以给定的方式分解列表



给定一个整数列表,任务是编写一个函数,该函数将输出另一个整数清单。很难用语言说出所需输出的性质,我正在写一些例子:

# list with one element will be returned
>>> func([[1, 2, 3, 4]])
[[1, 2, 3, 4]]
>>> func([[1], [1, 2]])
[[1], [2]]
>>> func([[1, 2], [1]])
[[1], [2]]
>>> func([[1], [1, 2, 3]])
[[1], [2, 3]]
>>> func([[1], [1, 2, 3], [1, 4]])
[[1], [2, 3], [4]]
>>> func([[1, 2], [2, 3]])
[[1], [2], [3]]
>>> func([[1], [2], [1, 2, 3]]) 
[[1], [2], [3]]
>>> func([[1, 2], [1, 2, 3]])
[[1, 2], [3]]
>>> func([[1], [1, 2], [1, 2, 3]])
[[1], [2], [3]]

(更新(您可以使用以下先决条件:

  1. 每个内部列表都包含已排序的整数,并且没有重复条目。

  2. 外部列表没有重复条目。

(更新(正如你所问,以下是我认为我坚持的:

这是有向图上的一些优化问题,将数字作为节点,将内部列表作为边的起点(外部列表是所有边的起点集(。现在,你可能会问,"一条边怎么会有多个起点,这在一些测试用例中显示出来?">

这就是我试图做的:对于CCD_ 1;节点2可以合并为单个节点。输出[1, 2]表明这两者可以合并。

现在来看func ([[1], [1, 2]])。第二内部列表尝试合并节点1&2在一起,但第一个内部列表表示节点1不能合并到任何内容。因此,输出为[[1], [2]],表示节点1&节点2将保持分离。

对于func ([[1], [2, 3], [1, 2, 3]]),节点1将被分离,但是节点2&3可以合并;因此输出为[[1], [2, 3]]

func ([[1, 2], [2, 3]])的情况下,节点1&2或2&3可以合并为节点1&3可以合并,因此预期结果是[[1], [2], [3]]

还有一个整数列表,它由顶点的端点组成,每个整数对应于每个内部列表。当内部列表的元素合并为一个时,只剩下一条边。当它们被分离时,会有单例列表,每个列表中的元素都被作为起点;端点的列表被相应地更新。

我想这会帮助你实现我的需求。

这依赖于按升序排序的列表列表(输出需要排序(,但适用于截至发布时提供的所有输入。

def removeFromList(elementsToRemove):
    def closure(list):
        for element in elementsToRemove:
            if list[0] != element:
                return
            else:
               list.pop(0)
    return closure
def func(listOfLists):
    result = []
    for i, thisList in enumerate(listOfLists):
        result.append(thisList)
        map(removeFromList(thisList), listOfLists[i+1:])
    return result

您可以使用更多的for循环来移除闭包,但它看起来太难看,嵌套太深。

编辑:基于更新,这是实际问题的天真解决方案:

from itertools import combinations
def isSubsetOrDisjointTo(listA, listB):
    return all(item in listB for item in listA) or all(item not in listB for item in listA)
def func(nodesToJoin):
    #flatten list, extracting duplicates
    allNodes = sorted(set(itertools.chain(*nodesToJoin)))
    result = []
    seen = set()
    for length in xrange(max(map(len, nodesToJoin)), 0, -1): 
        #start with longest possible, work to shortest
        for sublist in combinations(allNodes, length):
            if any(item in seen for item in sublist):
                #skip possible sublists with options we've already seen in the result
                continue
            if all(isSubsetOrDisjointTo(sublist, node) for node in nodesToJoin):
                result.append(sublist)
                seen.update(sublist)
    return result

这可能有很多方法可以优化或改进。

def func(L):
    r = [L[0]]
    for i in range(1, len(L)):
        r.append(list(set(L[i]) - set(L[i-1])))
    return r
def f (L):
    return [[l for l in L[i] if l not in sum(L[:i], [])] for i in range(len(L))]

编辑:OP一直在改变测试结果的含义,所以我不知道,这为我写它时的所有测试提供了正确的答案。

最新更新