Reputation: 185
I am using the following script to compare the elements in two separate lists in Python3. If an element matches e.g. element [0]
from list one matches element [0]
from list two then the variable c
is incremented by one. If the element does not match but the value is in the list then a different variable d
is incremented.
I have put the code together but it is rather long and wanted to know if it could be condensed in some way.
a = [1,2,3,4]
b = [2,1,3,4]
c = 0
d = 0
if a[0] == b[0]:
c += 1
elif a[0] == b[1] or a[0] == b[2] or a[0] == b[3]:
d += 1
if a[1] == b[1]:
c += 1
elif a[1] == b[0] or a[1] == b[2] or a[1] == b[3]:
d += 1
if a[2] == b[2]:
c += 1
elif a[2] == b[0] or a[2] == b[1] or a[2] == b[3]:
d += 1
if a[3] == b[3]:
c += 1
elif a[3] == b[0] or a[3] == b[1] or a[3] == b[2]:
d += 1
Upvotes: 0
Views: 193
Reputation: 4318
a = [1,2,3,4]
b = [2,1,3,4]
match = [a[i] == b[i] for i in range(len(a)) if a[i] in b]
c = sum(match)
d = len(match)-c
In this code match
consists of boolean values, for matchings locations per members in the intersection of a
and b
.
This code will perform similarly to what was asked in the question. However, if the intention is to use it like mastermind game, this won't work. For example, if a=[1,2,3,4]
and b=[4,4,4,4]
the matching indicator must be: 1/1
. The following code would do:
a = [1,2,3,4]
b = [4,4,4,4]
c = sum([a[i] == b[i] for i in range(len(a)) if a[i] in b])
d = sum([min(b.count(item), a.count(item)) for item in set(a)]) - c
Similar to the first guess in following game screenshot:
Upvotes: 1
Reputation: 152647
Yes, it can be condensed by using a for
-loop and you can also make it more performant by doing the elseif
(in Python this is called elif
) check on a set
.
a = [1,2,3,4]
b = [2,1,3,4]
c = 0
d = 0
b_set = set(b)
for item_from_a, item_from_b in zip(a, b):
if item_from_a == item_from_b:
c += 1
elif item_from_a in b_set:
d += 1
With zip
one iterates over both lists at once, so it will in the first iteration access the first element from a
and b
(i.e. 1
and 2
) in the second iteration it will access the second element from both lists (2
and 1
) and so on. You could also write it as loop over the indices (it's not as "clean" as using zip
but maybe easier to understand):
for idx in range(len(a)):
item_from_a = a[idx]
item_from_b = b[idx]
if item_from_a == item_from_b:
c += 1
elif item_from_a in b_set:
d += 1
The loop body itself should be fairly straightforward but please leave a comment if some part needs more explanation.
Upvotes: 0
Reputation: 351
Instead of the elif
statement you can use in
. Let's look an example:
I have this list: a = [1, 2, 3]
. 0 in a
returns False
but 1 in a
returns True
.
So, your code will look like this:
a = [1,2,3,4]
b = [2,1,3,4]
c = 0
d = 0
if a[0] == b[0]:
c += 1
elif a[0] in b:
d += 1
if a[1] == b[1]:
c += 1
elif a[1] in b:
d += 1
if a[2] == b[2]:
c += 1
elif a[2] in b:
d += 1
if a[3] == b[3]:
c += 1
elif a[3] in b:
d += 1
Upvotes: 0
Reputation: 616
You can just do this.
c = [e[0]==e[1] for e in [*zip(a,b)]].count(True)
d = [e in b for e in a].count(True) - c
Upvotes: 0