0
conditions = [1, 2, 3, 4]
values = [1, 2, 3, 3]

[print("YAY") for c,v in zip(conditions,values) if c==v]

This works but if I add an else statement as in the following example it raises a syntax error:

[print("YAY") for c,v in zip(conditions,values) if c==v else print("NAY")]

why is it forbidden to do so? would have made full of sense if it had worked (at least for me)

  • 5
    Because the `if` clause in a list comprehension determines whether the item is included in the list. The `else` is already known: not including the item! Also, you're building up a list of `None` and throwing it away and there's no point in that. It seems like you don't really understand what a list compression is intended to do. – kindall Jan 30 '19 at 03:19
  • 1
    [This](https://stackoverflow.com/questions/5753597/is-it-pythonic-to-use-list-comprehensions-for-just-side-effects) is related. – iz_ Jan 30 '19 at 03:25

2 Answers2

1

I agree with @kindall's answer, if you still want to print, you can change your codes like this, which will do as you expected:

conditions = [1, 2, 3, 4]
values = [1, 2, 3, 3]

list(map(lambda b: print("YAY") if b else print("NAY"), (c == v for c, v in zip(conditions, values))))
# YAY
# YAY
# YAY
# NAY
Menglong Li
  • 2,177
  • 14
  • 19
  • You can still use a list comprehension with `[print("YAY" if c == v else "NAY") for c, v in zip(conditions, values)]` – iz_ Jan 30 '19 at 03:25
  • @Tomothy32, yeah, I also thought of that in first sight, but considering we don't Py2 or Py3 the user is using, I just provide a compatible way to handle this, print("YAY" if c == v else "NAY") will not work for Py2, due to print is not a function, unless import print function from future. – Menglong Li Jan 30 '19 at 03:28
  • This answer was also very helpful! Now I understand better the @kindall's point. Thanks. – libensvivit Jan 30 '19 at 03:48
0

For singular if, the syntax is:

[print("YAY") for c,v in zip(conditions,values) if c==v]

This translates to:

for c,v in zip(conditions,values):
    if c==v:
        print('YAY')

For multiple if and elif and else, the syntax is:

[print("YAY") if c==v else print("lalala") if c=='some other condition' else print("NAY") for c,v in zip(conditions,values)]

This translates to

for c,v in zip(conditions,values):
    if c==v:
        print('YAY')
    elif c=='some other condition':
        print('lalala')
    else:
        print('NAY')

We can test this:

conditions = [1, 2, 3, 4, 'some other condition']
values = [1, 2, 3, 3, 999]
[print("YAY") if c==v else print("lalala") if c=='some other condition' else print("NAY") for c,v in zip(conditions,values)]
#YAY
#YAY
#YAY
#NAY
#lalala

EDIT: If you want to handle nested for loops in list comprehension, note that the following code are equivalent:

newlist = []
for c in conditions:
    for v in values:
        newlist.append((c,v))
print (newlist)
# [(1, 1), (1, 2), (1, 3), (1, 3), (1, 999), (2, 1), (2, 2), (2, 3), (2, 3), (2, 999), (3, 1), (3, 2), (3, 3), (3, 3), (3, 999), (4, 1), (4, 2), (4, 3), (4, 3), (4, 999), ('some other condition', 1), ('some other condition', 2), ('some other condition', 3), ('some other condition', 3), ('some other condition', 999)]

and

newlist = [(c,v) for c in conditions for v in values]
print (newlist)
#[(1, 1), (1, 2), (1, 3), (1, 3), (1, 999), (2, 1), (2, 2), (2, 3), (2, 3), (2, 999), (3, 1), (3, 2), (3, 3), (3, 3), (3, 999), (4, 1), (4, 2), (4, 3), (4, 3), (4, 999), ('some other condition', 1), ('some other condition', 2), ('some other condition', 3), ('some other condition', 3), ('some other condition', 999)]

Note that for c in conditions is the outer loop and for v in values is the inner loop for both snippets of code

ycx
  • 3,155
  • 3
  • 14
  • 26
  • This was very helpful! As I understand I should aim to keep the `for` clause at the end. Right? – libensvivit Jan 30 '19 at 03:40
  • @infinatronium Generally that is the case. However if there are 2 `for` loops aka nested `for` loops, the syntax order for list comprehension changes too. I'll edit the answer to showcase 1 example of this – ycx Jan 30 '19 at 06:58