Python summing values in list if it exists in another list

后端 未结 5 536
青春惊慌失措
青春惊慌失措 2021-01-26 11:48

I have a list and a set:

a_list = [[\'1\', 2], [\'2\', 1], [\'1\', 1]]

b_list = {\'1\', \'2\'}

I\'m looking to correspond the items in b_list

相关标签:
5条回答
  • 2021-01-26 11:58

    This returns sums only for items defined in find.

    items = [['1', 2], ['2', 1], ['1', 1], ['3',1]]
    find = {'1', '2'}
    results = {}
    
    for item in items:
        key = item[0]
        value = item[1]
        if key in find:
            results[key] = results.get(key,0) + value
    
    [[key, value] for key, value in results.items()] 
    
    

    Outputs [['2', 1], ['1', 3]]

    0 讨论(0)
  • 2021-01-26 12:02

    You are on the right track! All you have to do is flip the order of your loops. For every value in b_list, you want to sum up all matching values in a_list, so b_list should be the external loop and a_list the internal. Also note your sum variable should be inside the first loop as it is different for every value in b_list.

    If you make this change your code works as expected:

    a_list = [['1', 2], ['2', 1], ['1', 1]]
    
    b_list = {'1', '2'}
    
    for j in b_list:
        sum = 0
        for i in a_list:
            if i[0] == j:
                sum += i[1]
        print(j, sum)
    

    will give your desired output:

    ('1', 3)
    ('2', 1)
    

    EDIT: the above solution is a minimal fix to the code posted in the question, however there are more efficient solutions:

    Similar to wim's answer, you could use a defaultdictionary, which in this case would be (slightly) more efficient than using the built-in dict class:

    from collections import defaultdict
    #
    a_list = [['1', 2], ['2', 1], ['1', 1]]
    b_list = {'1', '2'}
    
    dict = defaultdict(int)
    
    for key, val in a_list:
        if key in b_list:
            dict[key] += val
    
    print([[key, dict[key]] for key in b_list])
    

    ** credit to coldspeed for the idea for this second solution.

    0 讨论(0)
  • 2021-01-26 12:02
    In [1]: a_list = [['1', 2], ['2', 1], ['1', 1]]
       ...:
       ...: b_list = {'1', '2'}
    
    In [2]: out = [[i, sum(j[1] for j in a_list if j[0] == i)] for i in b_list]
    
    In [3]: out
    Out[3]: [['1', 3], ['2', 1]]
    

    You can use sum of list or you can directly call sum. Here is a time performance of both approach:

    In [6]: %timeit [[i, sum(j[1] for j in a_list if j[0] == i)] for i in b_list]
    1.31 µs ± 2.52 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    In [7]: %timeit [[i, sum([j[1] for j in a_list if j[0] == i])] for i in b_list]
    1.2 µs ± 1.67 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    0 讨论(0)
  • 2021-01-26 12:17

    Use a dict for grouping:

    d = {}
    for k, v in a_list:
        d[k] = d.get(k, 0) + v
    print([[k, d[k]] for k in b_list])
    

    prints:

    [['2', 1], ['1', 3]]
    
    0 讨论(0)
  • 2021-01-26 12:18

    Accumulate numbers using a dict, and then gather the results using a list comprehension:

    >>> d = dict.fromkeys(b_list, 0)
    >>> for k, n in a_list: 
    ...     if k in d: 
    ...         d[k] += n 
    ...
    >>> [[k, n] for k, n in d.items()]
    [['1', 3], ['2', 1]]
    
    0 讨论(0)
提交回复
热议问题