0
loopCount = 0
candidateName = input("Please input the candidates name or type 'DONE' when finished:")
votes = []
while candidateName != "DONE":
     departmentName = input("Please input the department that submitted votes for this candidate:")
     numberOfVotes = input("Please input the number of votes for this candidate:")
     votes.append([])
     votes[loopCount].append(candidateName)
     votes[loopCount].append(departmentName)
     votes[loopCount].append(numberOfVotes)
     print(votes[loopCount])
     loopCount = loopCount + 1
     candidateName = input("Please input the candidates name or type 'DONE' when finished:")

print(votes)

sum = 0
for i in range(0,len(votes)):

This is my code I currently have. I believe what I need done can be done with a for loop. What I'm trying to do is cycle through the list, and add total up each candidate's vote count. Of course, if a candidate has a matching name I would need it to be correctly allocated. If anyone can please just point in the right direction on how I can process a list in this fashion. The multidimensional list is what's throwing me off. Any tips or advice at all would be appreciated. Thank you.

  • 1
    Check out: `http://stackoverflow.com/a/16548787/4837005` and `https://pythonprogramming.net/python-3-multi-dimensional-list/` – Coolq B Apr 29 '17 at 00:02
  • did not get what are you trying to do with this code.. – Alg_D Apr 29 '17 at 00:05
  • You're right, you can do your `for`-loop like this: `total = 0; for i in votes: total += int(i[2]); print total;`, (aside: change variable name `sum` to a different name (**sum** is a keyword in python that you don't want to overwrite)) – chickity china chinese chicken Apr 29 '17 at 00:05
  • Basically what I'm trying to do is this: Take input for candidates name, the department that is submitting votes and a vote count they're submitting. Put that input in a two dimensional list in the format of [CandidateName, Department, VoteCount]. I want to process that two dimensional list to tally the votes for each specific candidate, say if Donald was given 23 votes, Sally given 25, and then Donald given 25 again per input from the user. I want to be able to total 48 for Donald based on the name matching in the list. – jean wilders Apr 29 '17 at 00:06
  • your `for`-loop can also be replaced with this one-liner (a list-comprehension): `total = sum([v[2] for v in votes])` – chickity china chinese chicken Apr 29 '17 at 00:10
  • That does work. But how would that function with multiple candidates getting varying votes out of order? If that makes sense. – jean wilders Apr 29 '17 at 00:15
  • You mean you want to get individual sums for each candidate? – chickity china chinese chicken Apr 29 '17 at 00:16
  • Yes, that's exactly what I mean. – jean wilders Apr 29 '17 at 00:17
  • Do you need to keep the department names and vote breakouts for anything, or can you just tally votes as they come in? In other words, do you really need that 2-D list for later use, or do you only need the vote totals by candidate? – Prune Apr 29 '17 at 00:21
  • The department names really can be excluded logic wise, they aren't outputted. I could tally the votes as they came in, but how would I separate them correctly between candidates? – jean wilders Apr 29 '17 at 00:23
  • salparadise just posted the solution I was going to give you. – Prune Apr 29 '17 at 00:23

4 Answers4

2

So, what you are looking for is a key,value structure your data such as a python dictionary. Since this is two dimensional (candidate name and department name) you need a nested dictionary.

Python does not allow autovification like perl, so you want to use defaultdict to automatically allow you to use the nested structure like a dictionary.

Here is a refactored version:

from collections import defaultdict
candidates_and_votes = defaultdict(dict)
while True:
     candidateName = input("Please input the candidates name or type 'DONE' when finished:")
     if candidateName == 'DONE':
         break
     departmentName = input("Please input the department that submitted votes for this candidate:")
     numberOfVotes = input("Please input the number of votes for this candidate:")
     candidates_and_votes[candidateName][departmentName] = numberOfVotes

for candidate, department in candidates_and_votes.items():
    total = 0
    print('Candidate Name {}'.format(candidate))
    for dep_name, number in department.items():
        print('  Dep {}. total {}'.format(dep_name, number))
        total += int(number)
    print('     Total Votes = {}'.format(total))
salparadise
  • 5,699
  • 1
  • 26
  • 32
0

My take. There are fancier ways, but it works

totalvotes = {}
for i in range(0,len(votes)):
     if not votes[i][0] in totalvotes:
          totalvotes[votes[i][0]] = 0
     totalvotes[votes[i][0]] = totalvotes[votes[i][0]]+int(votes[i][2])
print(totalvotes)

or more compact

totalvotes = {}
for vote in votes:
    totalvotes[vote[0]] = totalvotes[vote[0]]+int(vote[2]) if vote[0] in totalvotes else int(vote[2])  
print(totalvotes)

The freaky one-liner:

print([(gk,sum([int(v[2]) for v in gv] )) for gk, gv in itertools.groupby( sorted(votes,key=lambda x:x[0]),lambda x: x[0])])
Diego Amicabile
  • 579
  • 4
  • 12
0

I would use python dictionary. Modify your code as needed.

votes = [['a','d',3],['b','d',3],['a','d',2]]

unique_names_list = {}
for ballot in votes:
    name = ballot[0]
    department = ballot[1]
    votes = ballot[2]

    name_depart = name + '-' + department

    if name_depart not in unique_names_list.keys():
        unique_names_list[name_depart] = votes
    else:
        unique_names_list[name_depart] = unique_names_list[name_depart] + votes
MLhacker
  • 1,382
  • 4
  • 20
  • 35
  • `name_depart not in unique_names_list.keys()` is an anti-pattern. In Python 2, `my_dict.keys()` *creates a list of keys* and then does a O(n) membership test! But if you want to check if a key is in `some_dict`, then all you need is `key in some_dict`, which will have O(1) performance! In Python 3, `my_dict.keys()` returns a *view* of the keys that mantains constant-time membership testing, but it is still redundant. – juanpa.arrivillaga Apr 29 '17 at 00:39
0

You would just need to process the results that your code is currently collecting. One way to do that would be like this:

canidates = []
loopCount = 0
candidateName = input("Please input the candidates name or type 'DONE' when finished:")
votes = []
while candidateName != "DONE":
     departmentName = input("Please input the department that submitted votes for this candidate:")
     numberOfVotes = input("Please input the number of votes for this candidate:")
     votes.append([])
     votes[loopCount].append(candidateName)
     votes[loopCount].append(departmentName)
     votes[loopCount].append(numberOfVotes)
     print(votes[loopCount])
     loopCount = loopCount + 1
     candidateName = input("Please input the candidates name or type 'DONE' when finished:")

results = []

#Tally the votes
for v in votes:
    if v[0] in canidates:
        #need to add these votes to an existing canidate.
        for x in results:
            #goes through each record in results and adds the record to it.
            if x[0] == v[0]:
                x[1] = x[1] + ", " + v[1]
                x[2] = x[2] + int(v[2])
    else:
        #need to create a new record for the canidate.
        canidates.append(v[0])
        results.append([v[0],v[1],int(v[2])])


#Display the results
print ("Vote Results:")
for x in results:
    print ("name: " + x[0])
    print ("Departments: " + x[1])
    print ("Votes Total: " + str(x[2]))

So what you would do is go through and combine the entries when there are multiple entries for the same canidate name.

Gaelephor
  • 11
  • 2