Reputation: 25
I am looking for an lambda expression to print an integer if a given string is in a given sentence separated by /
. This is the statement I wrote:
hunter = udf(lambda x : 'opened' in x.lower().split() print(10) elif 'clickedurl' in x.lower().split() print(20) else print("null"))
s= it/is/opened/memory/tae
hunter(s)
I am getting the following error
File "/home/main.py", line 1
hunter = udf(lambda x : 'opened' in x.lower().split() print(10) elif 'clickedurl' in x.lower().split() print 20 el
se print("null"))
^
SyntaxError: invalid syntax
Upvotes: 0
Views: 2094
Reputation: 365915
You have multiple syntax errors in your code, and you have to fix all of them.
First, lambda
expressions—like all expressions—cannot have statements in them, only expressions.
And that includes Python 2's print
statement, which you appear to be using.
If you want to write a function that includes a statement, you need to use a def
statement, not a lambda
expression.
Second, if you were trying to write an if-else
expression, you got the syntax for that wrong. You need to put the true-expression first, then if
, then the condition to check, then else
, then the false-expression.
You appear to have been trying to put the condition first, right before the true-expression:
'opened' in x.lower().split() print(10)
You can't do that. And that's where your first SyntaxError
, the one you're asking about, comes from.
Third, you cannot use elif
in an if-else
expression. You'd have to write it into an if-else
expression with another if-else
expression as the false-value.
Which is going to look horrible. If you find yourself needing that, you almost certainly want to break it out into an if
statement instead.
Also, while it isn't illegal, it's highly misleading to use an if-else
expression for its side effects.. if-else
expressions are about picking one value or another, not about running one set of side effects or another. If the latter is what you want, you want an if
statement.
And the same is true for lambda
. That's about defining functions that compute values; a function that's only called for its side effects should almost always be a def
.
So, what you want is this:
def thingy(x):
if 'opened' in x.lower().split():
print(10)
elif 'clickedurl' in x.lower().split():
print(20)
else:
print('null')
hunter = udf(thingy)
And notice that this gives you the opportunity to improve things (both readability and performance) by avoiding some repetition:
def thingy(x):
words = x.lower().split()
if 'opened' in words:
print(10)
elif 'clickedurl' words:
print(20)
else:
print('null')
Although of course you don't want to use names like x
and thingy
. I have no idea what any of these things represent, but surely you do.
And finally, I don't know what that udf
function is, but I can't imagine it returning anything useful when called with a function that always returns None
, so I'll bet you have more problems beyond these, but hopefully you can solve them from here.
And of course once you fix all of that, the next line is also a syntax error:
s= it/is/opened/memory/tae
This is attempting to divide a bunch of things. Even if it
, opened
, memory
, and tae
are all variables with relevant values, is
certainly isn't, because it's a built-in operator, so you can't divide anything by it.
You probably wanted a string here.
Also, because you're calling split()
without any argument, that's only going to split things separated by whitespace. So, either you wanted split('/')
above, or you wanted whitespace here.
So:
s = 'it is opened memory tae'
If you really wanted to make this one giant expression, it's possible, but it's going to be very, very ugly.
First, you have to replace that print
statement with a function call. Of course you could from __future__ import print_function
, but otherwise, you need to write a function that does what you want, or use one that already exists.
Second, you either need an if-else
inside an if-else
as the argument to that function, or you need to call that function in each branch of an if-else
in an if-else
. I think the first is slightly less horrible.
So:
lambda x: sys.stdout.write(
str(10 if 'opened' in x.lower().split() else (
20 if 'clickedurl' in x.lower().split() else 'null'))
+ '\n')
And of course inside an expression, whitespace doesn't matter, so you can freely rewrite that to be even uglier if you want:
lambda x:sys.stdout.write(str(10 if 'opened' in x.lower().split() else(20 if 'clickedurl' in x.lower().split() else 'null'))+ '\n')
… or:
lambda x: sys.stdout.write(str
(10
if 'opened' in x.
lower
(
).
split() else (20
if 'clickedurl' in x.lower().split() else 'null'))+ '\n')
I can't imagine why you'd want the latter, but then I can't imagine why you'd want the former either, and yet you seemed to be trying to write something as much like that as possible, so… go for it.
Upvotes: 3