-1

Here's what I'm trying to do (in a single list comprehension):

1. Compare the the relation of 2 bool-integer lists using logical operators
2. Return a list of bool-int values where:
- 1 is returned when both a,b values are 1 (1,1)
- 0 is returned when a==1 and b==0 (1,0)
- other cases are skipped, as in (0,0 & 0,1)

Example Logic:

A = [1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,0]
B = [1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]
L = []

for i in range(len(B)):
    if A[i] + B[i] == 2:
        L.append(1)
    elif A[i]==1 and B[i]==0:
        L.append(0)

Expected Output for print(L):

[1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1]

My Attempt: (syntaxError points to the 'for')(and it's a bit long)

L = [1 if x+y == 2 else 0 if x-y == 1 for x,y in zip(A, B)]  

Best Answer by Wander Nauta (Pythonic and fast)

L = [y for x, y in zip(A, B) if x]  

.
Couple of My Reference Points:
- add-sum-of-values-of-two-lists-into-new-list
- if-else-in-a-list-comprehension
- elif-in-list-comprehension-conditionals

Use Cases:
- Comparing lists representing the set of features (un)desired by a user/customer, and (un)available for a given product/service
- The returned 1's would represent desires_met and 0's would represent desires_unmet
- Further derivatives/analysis could easily be done on the boolean list returned.

  • Why do you want to use a list comprehension for this? It will make your code hard to read for no benefit. –  Nov 08 '17 at 23:14
  • Welcome to SO! To address your question regarding the syntax error - that's because you don't have a default value for fallback. What if x+y is not 2 and x-y is not 1? – Bahrom Nov 08 '17 at 23:15
  • @Blurp - Partly because I'm still learning list comprehension logic and structures, but also because I was interested to see if someone would come up with a creative shorter version, or a version that uses True/False logic as apposed to math operation (like "Wander Nauta's" awesome answer below). I comment my code well too, so I'm not too worried. – Jonathan Rolfsen Nov 09 '17 at 00:03
  • @Bahrom Thank you. I forgot those had to be handled in List Comps, I should've realized that from my 3rd resource listed. – Jonathan Rolfsen Nov 09 '17 at 00:05
  • Even if you comment your code well, nesting ternaries in a comprehension is pretty unreadable, especially for anyone else trying to understand your code. Also, other clever solutions that don't involve ternaries may still be hard to understand. Readability is almost always more important (and more Pythonic) than shorter code. –  Nov 09 '17 at 00:09
  • Sure, there's a trade-off, but I'm talking about the difference of, typically, a few lines for the sake of readability, not 4 times more code. –  Nov 09 '17 at 00:47
  • @Bahrom Do you have any recommendations for how I should make posts in the future? I just updated the post, but prior I had gotten down-voted. – Jonathan Rolfsen Feb 21 '18 at 06:05

3 Answers3

0

How's this?

L = [int(y) for x, y in zip(A, B) if int(x)]

If x is 0, the item is skipped. Otherwise, if y is 1, add 1; if y is 0, add 0.

Wander Nauta
  • 18,832
  • 1
  • 45
  • 62
0

I think something like this would be much easier to read and extend:

A = '11111111111000000010'
B = '11101010101010101010'

result_map = {
    ('1', '1'): 1,
    ('1', '0'): 0,
}

result = [result_map[pair] for pair in zip(A, B) if pair in result_map]
0

The question is rather convoluted but what I believe you want is this:

a = [int(x) for x in A] 
b = [int(x) for x in B]
c = [x for x in zip(a, b)]
I = [idx for (idx, x) in enumerate(a) if x == 0]
L = [x for (idx, x) in enumerate(b) if idx not in I]
rincewind
  • 2,502
  • 19
  • 26
nesaboz
  • 31
  • 5