代码之家  ›  专栏  ›  技术社区  ›  Mathieu

跟踪计算的子集以避免混合结果

  •  0
  • Mathieu  · 技术社区  · 6 年前

    棘手的名字和不清楚的名字…

    我的问题是:

    import itertools
    
    t0 = 0
    tf = 1000000
    # inputs_to_compute = list-like of size 2 to 6 of objects
    
    results = [[] for i in range(len(inputs_to_compute))]
    
    for subset in itertools.combinations(inputs_to_compute, 2):
        r1, r2 = compute(subset[0], subset[1], t0, tf)
        results[inputs_to_compute.index(subset[0])] += list(r1)
        results[inputs_to_compute.index(subset[1])] += list(r2)
    

    此代码创建的结果列表与输入的结果列表一样多。每个输入实际上都与一个列表相关联。然后按2乘2(在每个子集上)执行计算,并将结果添加到相应的列表中。

    只要输入中没有重复,它就工作得很好,因为该方法 index 返回元素的第一个匹配项。我怎样才能以一种管理重复的方式以不同的方式(高效地,性能是我的主要问题之一)实现这一点?

    虚拟示例:

    import itertools
    
    def compute(x, y):
        return (x + y, x - y)
    
    inputs_to_compute = [1, 1, 3]
    
    results = [[] for i in range(len(inputs_to_compute))]
    
    for subset in itertools.combinations(inputs_to_compute, 2):
        r1, r2 = compute(subset[0], subset[1])
        results[inputs_to_compute.index(subset[0])].append(r1)
        results[inputs_to_compute.index(subset[1])].append(r2)
    

    输出:

    [[2, 0, 4, 4], [], [-2, -2]]
    

    预期输出:

    # Iteration (1, 1): r1 = 2, r2 = 0
    results = [[2], [0], []]
    # Iteration (1, 3): r1 = 4, r2 = -2
    results = [[2, 4], [0], [-2]]
    # Iteration (1, 3): r1 = 4, r2 = -2
    results = [[2, 4], [0, 4], [-2, -2]]
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   yk4ever    6 年前
    for subset_with_indices in itertools.combinations(enumerate(inputs_to_compute), 2):
        i1,x1 = subset_with_indices[0]
        i2,x2 = subset_with_indices[1]
        r1, r2 = compute(x1, x2)
        results[i1].append(r1)
        results[i2].append(r2)
    
        2
  •  1
  •   Ashwini Chaudhary    6 年前

    如果我理解正确,那么你就要在重复的 1 每次它们作为 subset .

    实现这一点的一种方法是创建一个字典,其中项作为键,其索引存储在列表中。一旦我们有了这个口述,我们就可以申请了 itertools.cycle 到列表中,然后使用 next() 在项目索引之间循环:

    import itertools
    
    
    def compute(x, y):
        return (x + y, x - y)
    
    inputs_to_compute = [1, 1, 3]
    
    indices = {}
    for ind, item in enumerate(inputs_to_compute):
        indices.setdefault(item, []).append(ind)
    
    for k, v in indices.items():
        indices[k] = itertools.cycle(v)
    
    results = [[] for i in range(len(inputs_to_compute))]
    
    for subset in itertools.combinations(inputs_to_compute, 2):
        r1, r2 = compute(subset[0], subset[1])
        results[next(indices[subset[0]])].append(r1)
        results[next(indices[subset[1]])].append(r2)
    

    输出:

    >>> %run so.py
    
    >>> results
    [[2, 4], [0, 4], [-2, -2]]
    
        3
  •  0
  •   bobrobbob    6 年前

    在文档中,您有一个使用排列组合的配方[1]。您只需修改它以返回索引

    import itertools
    
    def compute(x, y):
        return (x + y, x - y)
    
    def combinations(iterable, r):
        pool = tuple(iterable)
        n = len(pool)
        for indices in itertools.permutations(range(n), r):
            if sorted(indices) == list(indices):
                yield tuple(indices)
    
    inputs_to_compute = [1, 1, 3]
    
    results = [[] for i in range(len(inputs_to_compute))]
    for i1, i2 in combinations(inputs_to_compute, 2):
        r1, r2 = compute(inputs_to_compute[i1], inputs_to_compute[i2])
        results[i1].append(r1)
        results[i2].append(r2)
    
    print(results)
    

    [1] https://docs.python.org/3/library/itertools.html#itertools.combinations