Python 如果元组中的第一个元素与else匹配,则对元组元素进行乘法

Python 如果元组中的第一个元素与else匹配,则对元组元素进行乘法,python,python-2.7,tuples,multiplication,Python,Python 2.7,Tuples,Multiplication,我有一个元组列表,如下所示 [(0, 33), (3, 26), (4, 95), (0, 28), (1, 12), (2, 3), (4, 69)] 如果第一个元素匹配(一次或多次),我想乘以元组的第二个元素;如果不是,我忽略元组。因此,输出应该是 33 * 28 + 95 * 69 = 7479 目前,我正在做以下工作: 使用计数器检查元组的第一个元素是否存在 迭代集合以查看是否存在1元素元组或更多元组;忽略1个元素 迭代地将非1元素元组添加到字典中,并进行乘法更新 在字典的值上使用s

我有一个元组列表,如下所示

[(0, 33), (3, 26), (4, 95), (0, 28), (1, 12), (2, 3), (4, 69)]
如果第一个元素匹配(一次或多次),我想乘以元组的第二个元素;如果不是,我忽略元组。因此,输出应该是

33 * 28 + 95 * 69 = 7479
目前,我正在做以下工作:

  • 使用计数器检查元组的第一个元素是否存在
  • 迭代集合以查看是否存在1元素元组或更多元组;忽略1个元素
  • 迭代地将非1元素元组添加到字典中,并进行乘法更新
  • 在字典的
    值上使用
    sum
    函数

  • 我想知道是否有一种类似蟒蛇的方法来减少这种情况。我敢肯定,我把这里的事情弄得很复杂。

    我将编写类似这样的程序

    collection = [(0, 33), (3, 26), (4, 95), (0, 28), (1, 12), (2, 3), (4, 69)]
    output = 0
    for elem in collection:
        collection.remove(elem)
        new_collection = collection
        part_output = 0
        for new_elem in new_collection:
            if elem[0] == new_elem[0]:
                part_output = (part_output * new_elem[1]) if part_output != 0 else (elem[1] * new_elem[1])
                collection.remove(new_elem)
        output = output + part_output
    
    print output
    

    元组列表只迭代一次,元素被删除,因为这些元素不需要。

    奇怪的是,这个问题没有好的答案。。。 以下是我的看法:

    test = [(0, 33), (3, 26), (4, 95), (0, 28), (1, 12), (2, 3), (4, 69)]
    unique_keys = set([pair[0] for pair in test]) #{0, 1, 2, 3, 4}
    grouped_by_key = [[el[1] for el in test if el[0] == key] for key in unique_keys] # [[33, 28], [12], [3], [26], [95, 69]]
    grouped_by_key = filter(lambda x: len(x) > 1,grouped_by_key) # [[33, 28], [95, 69]]
    
    add = lambda x, y : x+y
    mul = lambda x, y : x*y
    # Alternatively:
    # from operator import add, mul
    
    out = reduce(add, map(lambda x: reduce(mul, x), grouped_by_key))  #7479
    

    我将使用
    reduce
    mul
    在按键拆分元组后获得列表的乘积:

    test = [(0, 33), (3, 26), (4, 95), (0, 28), (1, 12), (2, 3), (4, 69)]
    grouped_by_key = {pair[0] : [] for pair in test} #Initialize dict to hold items
    tmp = [grouped_by_key[pair[0]].append(pair[1]) for pair in test] #Add items in lists by keys
    
    现在导入一些东西:

    from functools import reduce #reduces iterables
    from operator import mul #helps doing multiply for a list
    
    现在使用导入的函数获得所需的结果:

    sum([reduce(mul,v,1) for v in grouped_by_key.values() if len(v) > 1])
    7479
    

    我会在混合中抛出一个
    defaultdict
    ,以简化匹配的组合。我还包含了生成方程本身的代码,可以注释掉:

    from collections import defaultdict
    from operator import mul
    
    pairs = [(0, 33), (3, 26), (4, 95), (0, 28), (1, 12), (2, 3), (4, 69)]
    
    table = defaultdict(list)
    
    for key, value in pairs:
        table[key].append(value)
    
    result = 0
    equation = []
    
    for value in table.values():
        if len(value) > 1:
            equation.append(' * '.join(map(str, value)))
            result += reduce(mul, value)
    
    print ' + '.join(equation), '=', result
    
    输出

    33 * 28 + 95 * 69 = 7479
    

    python的方法可能是这样的:拥有一个dict,其键是第一个元素,并且只沿着整个列表走一次,更新字典。每个值都包含诸如“是否看到了不止一个”和“这是目前为止这些项的结果”之类的信息。我想知道像
    ifilter
    这样的东西是否有帮助。在您的位置上,我会按照上面所述一步一步地编写算法,而不必担心某些itertools函数。这不会运行。除了缺少注释字符外,
    xx
    未定义。此外,一致的意见似乎是答案是7479,而不是7476XX位,它是重命名变量后的一个打字错误。而且我得到的结果是正确的…只是从控制台手动粘贴错误!感谢您在第二行中发现,您使用了三个概念
    set
    map
    lambda
    来获取唯一密钥,为什么不
    set([pair[0]表示测试中的pair])
    ?列表理解和听写理解非常方便。