-3

so I have two lists where I compare a person's answers to the correct answers:

correct_answers = ['A', 'C', 'A', 'B', 'D']
user_answers = ['B', 'A', 'C', 'B', 'D']

I need to compare the two of them (without using sets, if that's even possible) and keep track of how many of the person's answers are wrong - in this case, 3

I tried using the following for loops to count how many were correct:

correct = 0

for i in correct_answers:
    for j in user_answers:
        if i == j:
            correct += 1

print(correct)

but this doesn't work and I'm not sure what I need to change to make it work.

Remi Guan
  • 21,506
  • 17
  • 64
  • 87

3 Answers3

2

Just count them:

correct_answers = ['A', 'C', 'A', 'B', 'D']
user_answers = ['B', 'A', 'C', 'B', 'D']

incorrect = sum(1 if correct != user else 0
                for correct, user in zip(correct_answers, user_answers))
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
spectras
  • 13,105
  • 2
  • 31
  • 53
  • 1
    You can probably simplify it as `sum(answer1 != answer2 for answer1, answer2 in zip(correct_answers, user_answers))`. – alecxe Oct 28 '15 at 02:24
  • Though that would work, it would rely on the fact that `True == 1`, which is not very clean. – spectras Oct 28 '15 at 02:25
  • 1
    Or if you want to use the batteries even more (which pushes all the work to the C layer in CPython): `from operator import ne`, `sum(map(ne, correct_answers, user_answers))` – ShadowRanger Oct 28 '15 at 02:26
  • 1
    @spectras: In Python, `False` and `True` are explicitly and intentionally singleton instances of `bool`, a subclass of `int` with the values of `0` and `1` respectively. Using that fact is perfectly Pythonic; for stuff that definitely returns `bool`, you're not relying on implementation specific behavior or anything. This isn't Java, where `boolean` and `int` are completely incompatible to prove a point about purity. – ShadowRanger Oct 28 '15 at 02:28
  • @ShadowRanger I think your sum+map+ne option is too good to be a comment :) – alecxe Oct 28 '15 at 02:30
  • I agree on the principle, it's just I feel being explicit is better than being implicit. Summing bools relies on the hidden, implicit value of `True`. I like my code to show my intent, not my knowledge. :) – spectras Oct 28 '15 at 02:33
2

I blame @alecxe for convincing me to post this, the ultra-efficient solution:

from future_builtins import map  # <-- Only on Python 2 to get generator based map and avoid intermediate lists; on Py3, map is already a generator
from operator import ne

numincorrect = sum(map(ne, correct_answers, user_answers))

Pushes all the work to the C layer (making it crazy fast, modulo the initial cost of setting it all up; no byte code is executed if the values processed are Python built-in types, which removes a lot of overhead), and one-lines it without getting too cryptic.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

The less pythonic, more generic (and readable) solution is pretty simple too.

correct_answers = ['A', 'C', 'A', 'B', 'D']
user_answers = ['B', 'A', 'C', 'B', 'D']

incorrect = 0
for i in range(len(correct_answers)):
    if correct_answers[i] != user_answers[i]:
        incorrect += 1

This assumes your lists are the same length. If you need to validate that, you can do it before running this code.

EDIT: The following code does the same thing, provided you are familiar with zip

correct_answers = ['A', 'C', 'A', 'B', 'D']
user_answers = ['B', 'A', 'C', 'B', 'D']

incorrect = 0
for answer_tuple in zip(correct_answers, user_answers):
    if answer_tuple[0] != answer_tuple[1]:
        incorrect += 1
subdavis
  • 604
  • 7
  • 20
  • Moral: sometimes you should just go back to the basics. – ycsun Oct 28 '15 at 02:44
  • I have no objection to the explicit loop, but for the love of god, use `zip`, not C-style loops with indexing, and use `!=`, not `not x == y`. The former is recidivist C programmer design (which actually makes the code less readable, and less reliable, since `zip` with unpacking gives useful names and avoids out of bounds errors). The latter is just ugly. – ShadowRanger Oct 28 '15 at 02:53