teukteukteuk
teukteukteuk

Reputation: 45

How to add numbers in duplicate list

I've collected data from txt file and made it to the list (actually there are a lot more players, so it is impossible to count without loop), like:

data_list = [
['FW', '1', 'Khan', '2', '0'], 
['FW', '25', 'Daniel', '0', '0'], 
['FW', '3', 'Daniel', '1', '0'], 
['FW', '32', 'Daniel', '0', '0'], 
['FW', '4', 'Khan', '1', '0']
]

and I want to add the goal of each Khan and Daniel and make a list like:

['Khan', 3]
['Daniel', 1]

I have a name list (name_list = [Khan, Daniel])

I've tried to do with for loop, like:

goal = []
num = 0
for i in name_list:
        for j in data_list:
                if i == j[2]:
                        num += int(j[3])
                        goal.append([i, num])
                else:
                        continue

and it did not work. I am very novice, so your comments will be a really big help. Thanks!

Upvotes: 0

Views: 76

Answers (4)

cglacet
cglacet

Reputation: 10962

Your code is very close from working, there are syntax error and one single real problem.

The problem is that you are appending num too soon. You should sum over rows that contain the name you are looking for, then, once all rows have been seen append the value:

data_list = [
    ['pos', 'num', 'name', 'goal', 'assist'],
    ['FW', '1', 'Khan', '2', '0'], 
    ['FW', '25', 'Daniel', '0', '0'], 
    ['FW', '3', 'Daniel', '1', '0'], 
    ['FW', '32', 'Daniel', '0', '0'], 
    ['FW', '4', 'Khan', '1', '0']
]

name_list = ['Khan', 'Daniel']

goal = []
for name in name_list:
    total_score = 0
    for j in data_list:
        if name == j[2]:
            total_score += int(j[3])
    goal.append([i, total_score])

On the other hand this strategy is not the most efficient since for every name the code will iterate over all rows. You could (using dictionaries to store intermediate results) need a single look on each row, independently of the number of "names" you are looking for.

name_list = {'Khan', 'Daniel'}

goal = dict()
for row in data_list:
    if row[2] in name_list:
        if not row[2] in goal:
            goal[row[2]] = 0
        goal[row[2]] += int(row[3])

Which set goal to {'Khan': 3, 'Daniel': 1}.

Yet this could be improved (readability), using defaultdict. What default dictionary do is doing the existence check of a given "key" and initialisation automatically for you, which simplifies the code:

from collections import defaultdict 

goal = defaultdict(int)
for row in data_list:
    if row[2] in name_list:
        goal[row[2]] += int(row[3])

Which does the exact same thing as before. At that point it's not even clear that we really need to provide a list of names (unless memory is an issue). Getting a dictionary for all names would again simplify the code (we just need to make sure to ignore the first row using the slice notation [1:]):

goal = defaultdict(int)
for row in data_list[1:]:
    goal[row[2]] += int(row[3])

Upvotes: 3

wjandrea
wjandrea

Reputation: 33107

Don't bother doing it manually. Use a Counter instead:

from collections import Counter

c = Counter()
for j in data_list:
    name = j[2]
    goal = int(j[3])
    c[name] += goal

print(c.most_common())  # -> [('Khan', 3), ('Daniel', 1)]

Upvotes: 1

ncasale
ncasale

Reputation: 879

In your above code you increment the value of num without first defining it. You'll want to initialize it to 0 outside of your inner for loop. You'd then append the name/goal to the list like this:

for i in name_list:
    #Init num
    num = 0
    # Iterate through each data entry
    for j in data_list:
        if i == j[2]:
            # Increment goal count for this player
            num+= int(j[3])
    # Append final count to goal list
    goal.append([i, num])

This should have the desired effect, although as @wjandrea has pointed out, a Counter would be a much cleaner implementation.

Upvotes: 1

Murgalha
Murgalha

Reputation: 378

You can create a dictionary to keep the sum number of goals, with the names as keys. This will make easier to access the values:

goals_dict = {}
for name in name_list:
    goals_dict[name] = 0
# {'Khan': 0, 'Daniel': 0}

Then just sum it:

for name in name_list:
    for data in data_list:
        if data[2] == name:
            goals_dict[name] += int(data[3])

Now you will have your dictionary populated correctly. Now to set the result as the list you requested, do as such:

result = [[key, value] for key, value in d.items()]

Upvotes: 2

Related Questions