1

Given a list like:

[['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]

I need to add the components of the two lists that have the same first index like so:

[['james',300,500,700],['charles',200,200,100]]

Thanks for the answers. Just found out I have to do so without importing any modules. Is there a way to do so? I've tried using for-loops but cannot find out what to index for.

Joe Steele
  • 43
  • 4

4 Answers4

0
data=[['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]
dic={}
for sample in data:
    if sample[0] in dic.keys():
        dic[sample[0]] = [x+y for x,y in zip(dic[sample[0]],sample[1:])]
    else:
        dic[sample[0]] = sample[1:]
data= [[x]+y for x,y in dic.items()]

Explanation: The for loop iterates over all elements of the list. Using the 1st element of each list, we check if 'dic' has this name as a key or not. If yes, we add to previous values of the key else create the key with the values 'sample[1:]'.The last step converts dictionary 'dic' to the desired list

Mehul Gupta
  • 1,829
  • 3
  • 17
  • 33
0
dic = {}
for row in a:
    if row[0] in dic:
        dic[row[0]] = [sum(n) for n in zip(*[dic[row[0]], row[1:]])]
    else:
        dic[row[0]] = row[1:]

ans = []
for key in dic:
    ans.append([key, *dic[key]])

You can create a dictionary with the names as keys and the subsequent numbers as the value. Finally you can convert the dictionary to a list of lists.

[sum(n) for n in zip(*[dic[row[0]], row[1:]])] is used to sum up the elements of 2 corresponding lists, refer here : https://stackoverflow.com/a/11280563/10077354

Suraj
  • 2,253
  • 3
  • 17
  • 48
-1

you can use collections.defaultdict:

from  collections import defaultdict

l = [['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]


d = defaultdict(list)
for k, *v in l:
    d[k].append(v)

[[k, *[sum(e) for e in zip(*v)]] for k, v in d.items()]

output:

[['james', 300, 500, 700], ['charles', 200, 200, 100]]

without importing any module:

l = [['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]


d = {}
for k, *v in l:
    d.setdefault(k, []).append(v)

[[k, *[sum(e) for e in zip(*v)]] for k, v in d.items()]

output:

l = [['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]
kederrac
  • 16,819
  • 6
  • 32
  • 55
  • Slightly simpler: `d = defaultdict(lambda: [0,0,0])`, then the body of the loop `d[k][:] = map(operator.add, d[k], v)` gives you the sums without the need for the other list comprehension. – chepner Mar 26 '20 at 23:44
  • There's no good reason to avoid importing a module from the standard library. (`add`, at least, isn't really necessary; it's just more efficient than using `lambda x, y: x = y`.) – chepner Mar 27 '20 at 11:56
  • @chepner I agree with you, I guess it is another task from school, these teachers... – kederrac Mar 27 '20 at 11:58
-1

Hmm... no imports sounds like homework. Python is all about re-use. However, just for fun:

data = [['james', 100, 200, 300], ['james', 200, 300, 400], ['charles', 200, 200, 100]]


def combine_lists(data, result=None):
    if result is None:
        result = []
    if data:
        return combine_lists(data[1:], _add_sublist(data[0], result))
    return result


def _add_sublist(sublist, result):
    result_out = []
    combined = False
    for result_sublist in result:
        if sublist[0] == result_sublist[0]:
            result_out.append([sublist[0], *[from_elt + into_elt
                                             for from_elt, into_elt in zip(sublist[1:], result_sublist[1:])]])
            combined = True
        else:
            result_out.append(result_sublist)
    if not combined:
        result_out.append(sublist)
    return result_out

Running the function in a shell using your data:

In [4]: combine_lists(data)                                                                                                                        
Out[4]: [['james', 300, 500, 700], ['charles', 200, 200, 100]]

Make sure you understand the code before handing it in :)

Paul Whipp
  • 16,028
  • 4
  • 42
  • 54