Conversation started Oct 23, 2019 at 9:54.
Oct 23, 2019 09:54
# name: 3_fn_lambda.py

# function with no name
# has a list of parameters
# :
# a single expression
lambda x : x * x
print("res : ", (lambda x : x * x)(10))
f1 = lambda x, y : x * y
f2 = lambda x, y : x * y

print(f1, type(f1))
print(f2, type(f2))

print(f1(10, 20))
print(f2(10, 20))

# sort
a = ['abcd', 'XyZ', 'Abef', 'Bx', 'zss']
print(sorted(a))
# sort in a case insensitive way
print(sorted(a, key = str.upper))

a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]
# combine 0th and 2nd char
print(sorted(a, key = lambda s : s[0] + s[2]))
Give me a moment and I'll copy and run the code.
i don't undertand how the first one works
Do you mean: lambda x : x * x ?
print("res : ", (lambda x : x * x)(10))
what is 10 doing there
how do you use lambda
i wrote a program but it's not working
The expression lambda x : x * x evaluates to a function. If you type it at the console you'll see it eavluates to:
>>> lambda x : x * x
<function <lambda> at 0x00000272212070D8>
Oct 23, 2019 10:02
yes memory locatin
i got it too
So if I type foo = lambda x : x * x this defines a new function foo() that squares its parameter.
how do you put value for x
i dont understand
>>> foo = lambda x : x * x
>>> foo(2)
4
>>> foo(3)
9
OK so far?
But I can also skip assigning the new function to a variable like foo and just do:
>>> (lambda x : x * x)(2)
4
>>> (lambda x : x * x)(3)
9
Does that help?
Oct 23, 2019 10:05
yes
let me try
yep work
@JohnRennie What does sorted do
wait it is sorting
sorted is just a function that takes a list and returns a new list that is sorted.
so it's an extension of sort?
@JohnRennie a = ['abcd', 'XyZ', 'Abef', 'Bx', 'zss']
print(sorted(a))
# sort in a case insensitive way
print(sorted(a, key = str.upper))
mylist.sort does a sort in place i.e. it takes the list mylist and sorts it.
what is key
sorted(mylist) leaves mylist unchanged and returns a new list containing the same elements as mylist that is sorted.
So .sort() and sorted() both sort lists but they do it in different ways.
@Aladdin when you sort some collection you have to define how you want the sorting to work.
For example if you were sorting a box of apples you might choose to sort them by weight, or by size, or by how ripe they are and so on.
OK so far?
Oct 23, 2019 10:14
ok
In the sorted function the key parameter specifies how you want the list to be sorted.
ignore me
can u show example
An example of what?
sorted using key
We need to talk a bit about how sorting works.
Oct 23, 2019 10:18
ok
Suppose you have two strings x = "abc" and y = "def"
To sort the strings you need some way of finding out is x is less than, greater than or equal to y. OK so far?
By default sorted compares the strings character by character. So it looks at x[0] and y[0] and sees which is greater, lesser or equal.
If x[0] < y[0] then this means x < y and the comparison can stop immediately.
Oct 23, 2019 10:21
yep
If the first characters of the strings are identical then sorted moves on to look at x[1] and y[1].
If these are the same it moves on to x[2] and y[2] and so on until either it finds a difference or it comes to the end of the string.
But you can tell sorted to use a different way of comparing the strings.
And that's what key is used for.
Suppose I use sorted(mylist, key=str.upper)
The value of key is a function that is applied to the elements before comparing them. So in this case sorted would start by comparing str.upper(x[0]) and str.upper(y[0]).
So suppose x="aaa" and y="AAA"
if we compare the two we get y < x because the ASCII code for "A" is less than the ASCII code for "a". OK so far?
Oct 23, 2019 10:27
ok
But if we use key=str.upper then the function str.upper gets applied to the characters before sorted compares them. So in effect it is comparing str.upper(x) and str.upper(y) i.e. comparing "AAA" and "AAA". And of course they are the same.
So by setting key=str.upper we can do a sort where it doesn't matter if letters are upper or lower case.
>>> a = ['abcd', 'XyZ', 'Abef', 'Bx', 'zss']
>>> sorted(a)
['Abef', 'Bx', 'XyZ', 'abcd', 'zss']
>>> sorted(a, key=str.upper)
['abcd', 'Abef', 'Bx', 'XyZ', 'zss']
Can you see how this works? With sorted(a) the uppercase letters come before the lowercase letters. With sorted(a,key=str.upper) the case doesn't matter.
yeah
This is a simple case, but the function you use as a key could be any function you want including functions you define yourself.
Oct 23, 2019 10:34
@JohnRennie Why str.upper
instead of a.upper?
Because str.upper is the name of a global function that uppercases its argument. a.upper is a method of a specific variable a.
>>> str.upper("abc")
'ABC'
Actually I just checked and strings don't have a .upper method.
>>> a
['abcd', 'XyZ', 'Abef', 'Bx', 'zss']
>>> a.upper()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'upper'
aha thats why
@JohnRennie a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]

sorted(a,key=lambda a:a[0]+a[2])
why is this not working
>>> a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]
>>> sorted(a,key=lambda a:a[0]+a[2])
['axae', 'abcd', 'xwxz', 'xcyz']
It is working, but is it using a rather odd sort method.
Your sort function lambda a:a[0]+a[2] is adding together the first and third letters of the strings and using the result as the sort order.
Oct 23, 2019 10:49
it's not printing for me
You mean when you type sorted(a,key=lambda a:a[0]+a[2]) and press enter nothing happens?
no output is shown
no for this
a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]

sorted(a,key=lambda a:a[0]+a[2])
D:\rhs\Python>python
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]
>>>
>>> sorted(a,key=lambda a:a[0]+a[2])
['axae', 'abcd', 'xwxz', 'xcyz']
It works here. I just copied and pasted your code.
weird
Is that a blank line on your second line?
You haven't accidentally put some spaces there?
Oct 23, 2019 10:52
blank line
Don't know then.
@JohnRennie Sorry i put space
@Aladdin oops :-)
@JohnRennie a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]
# combine 0th and 2nd char
print(sorted(a, key = lambda s : s[0] + s[2]))
How does this work
The function you are specifying for the sorting is lambda s : s[0] + s[2]
Oct 23, 2019 10:58
why not a in there
This takes the first and third letters of the string and adds them.
@Aladdin it's the definition of a function
It's like:
def foo(s):
  return s[0] + s[2]
s is just the name the function uses for its parameter.
okay
@JohnRennie But it's not comining
combining 1st and 3nd character
s[0] is the first character of the string s and s[2] is the third character. And the function is returning s[0]+s[2].
>>> s="abc"
>>> s[0]+s[2]
'ac'
yes
but we want a not s
@JohnRennie hello?
print(sorted(a, key = (lambda s : s[0] + s[2]))(a))
s is just the name of the parameter as used in the function definition. It's like doing:
Oct 23, 2019 11:09
why so many brackets before a?
why not:
def foo(s):
  return s[0] + s[2]

a = "xyz"
foo(a)
print(sorted(a, key = (lambda s : s[0] + s[2])(a))
The variable you pass as the key to sorted has to be a function.
(lambda s : s[0] + s[2])(a) is not a function. It is the result returned by a function when you pass it the argument a.
ok
@JohnRennie How would change to a function
lambda s : s[0] + s[2] is the function.
Try typing that at the console and python will tell you it's a function:
>>> lambda s : s[0] + s[2]
<function <lambda> at 0x000001CF820D70D8>
Oct 23, 2019 11:16
so this code is wrong
a = [ 'abcd', 'axae', 'xcyz', 'xwxz' ]
# combine 0th and 2nd char
print(sorted(a, key = lambda s : s[0] + s[2]))
@JohnRennie
it can't combine oth and 2nd char
Lets simplify this to:
a = [ 'abcd', 'axae' ]
sorted(a, key = lambda s : s[0] + s[2])
So when we call sorted it has to compare the two strings 'abcd' and 'axae'. Yes?
Without a key it would just compare the letters, but are telling it to use the function lambda s : s[0] + s[2] to do the comparison.
For the first string we get (lambda s : s[0] + s[2])('abcd') = 'ac'
For the second string we get (lambda s : s[0] + s[2])('axae') = 'aa'
And 'aa' < 'ae' so the second string is less than the first string.
how is s==a?
lik how is s taking values of a
We have a conceptual difficulty here ...
Oct 23, 2019 11:24
sorry it's not becoming clear to me
Are you happy that the key function is lambda s : s[0] + s[2] i.e. a function that takes a string as an argument and returns a new string made up from the first and third characters of the original string?
And we'll use my simplified example with just two strings in the list:
a = [ 'abcd', 'axae' ]
sorted(a, key = lambda s : s[0] + s[2])
When you call sorted the sorted function takes its argument a and looks at the elements of the list a.
In this case there are only two elements: 'abcd' and 'axae'
Oct 23, 2019 11:27
and then it applies the function on it
So the sorted function takes the two elements a[0] and a[1] and checks to see which is less.
And the way it does this is using the function lambda s : s[0] + s[2]
So the sorted function calls (lambda s : s[0] + s[2])(a[0]) and it also calls (lambda s : s[0] + s[2])(a[1]) and it looks at the reults returned by the function to see which is less.
ohkay
so argument is a
parmeter is s
and then sorts based on the result from the unction
@JohnRennie Lat doubt
OK ... ?
Oct 23, 2019 11:34
@JohnRennie can you tell me why set and tuple doesn't work
for map example
It's because when you call list(v) it empties the map object v and puts all its entries in your list.
>>> v=map(fun,a)
>>> v
<map object at 0x000001CF820DE0C8>
>>> list(v)
[1, 4, 9, 25]
>>> list(v)
[]
So list(v) only works once. The second time it returns an empty list because the map object got emptied by the first call to list.
tuple and set will work if you call them immediately after the map
>>> v=map(fun,a)
>>> set(v)
{1, 4, 9, 25}
 
Conversation ended Oct 23, 2019 at 11:40.