Basic Python Training at Arcesium - Day 1

Apr 15-18, 2019 Vikrant Patil

These notes are available online at http://notes.pipal.in/2019/arcesium_basic_aug/day1.html

© Pipal Academy LLP

Day 1 | Day 2 | Day 3 | Day 4

We will be using python 3 (>= 3.0) from anaconda for this training. You can download it from

https://www.anaconda.com/download/

In [2]:
800000/12
Out[2]:
66666.66666666667
In [3]:
30 + 45
Out[3]:
75
In [4]:
45 -35
Out[4]:
10
In [5]:
34 * 15
Out[5]:
510
In [6]:
2**100
Out[6]:
1267650600228229401496703205376

header1

header2

Header3

# header1#
## header2##
### Header3###

Basic data types

integers **bold**

In [12]:
2 + 3 #addition
Out[12]:
5
In [13]:
2 -3 #substraction
Out[13]:
-1
In [14]:
3*4 # multiplication
Out[14]:
12
In [15]:
3/5 #foating point division 
Out[15]:
0.6
In [16]:
5//2 #integer division
Out[16]:
2
In [17]:
5%2 #mod
Out[17]:
1
In [18]:
2 ** 10 #power operator
Out[18]:
1024
In [19]:
5/2
Out[19]:
2.5
In [20]:
5//2
Out[20]:
2
In [22]:
2**100 #the size of integer is taken care by python. it supports really big numbers
Out[22]:
1267650600228229401496703205376
In [24]:
2**10000
Out[24]:
19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709376

floating point numbers , decimal numbers

In [25]:
2.5**4
Out[25]:
39.0625
In [26]:
3.6 /3
Out[26]:
1.2
In [27]:
3.6//3
Out[27]:
1.0
In [28]:
2 + 3*2 + 4**45*(2+1)
Out[28]:
3713820117856140824697372680

string

In [29]:
"arcesium"
Out[29]:
'arcesium'
In [30]:
2
Out[30]:
2
In [31]:
'arcesium'
Out[31]:
'arcesium'
In [32]:
"arcesium's location"
Out[32]:
"arcesium's location"
In [33]:
'he said,"I am fine!"'
Out[33]:
'he said,"I am fine!"'
In [34]:
"\""
Out[34]:
'"'
In [35]:
"star"*5
Out[35]:
'starstarstarstarstar'
In [36]:
"*"*5
Out[36]:
'*****'
In [37]:
"hello" "python"
Out[37]:
'hellopython'

Assignment operator

expression on right hand side is executed, result is computed and stored in memory. a name is given to this computed result, which is mentioned on lft hand side of = operator

name  = 2  + 4*(3-45)
In [38]:
x  = 1
In [39]:
x
Out[39]:
1
In [40]:
y = 3**5
In [41]:
y
Out[41]:
243
In [42]:
z = x+y
In [43]:
x = 34

Example

In [44]:
a = 2**5
In [45]:
a
Out[45]:
32
In [46]:
b = a
In [47]:
b
Out[47]:
32
In [48]:
a
Out[48]:
32
In [49]:
a = 3**5
In [50]:
a
Out[50]:
243
In [51]:
b
Out[51]:
32
In [52]:
**strings**
  File "<ipython-input-52-9d43adb611dd>", line 1
    **strings**
     ^
SyntaxError: invalid syntax

strings

In [53]:
star = "*"
In [54]:
fivestar = star*5
In [55]:
fivestar
Out[55]:
'*****'
In [56]:
print("Hello World!")
Hello World!
In [57]:
print(a)
243
In [58]:
print(a+b)
275
In [59]:
oneline = "This is just one liner"
In [60]:
print(oneline)
This is just one liner
In [61]:
import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
In [62]:
poem = """
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

"""
In [63]:
print(poem)
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!


In [64]:
multiplelines ="one\ntwo\nthree"
In [65]:
print(multiplelines)
one
two
three
In [66]:
multiplelines1 ="""
one
two
three
"""
In [67]:
print(multiplelines1)
one
two
three

In [68]:
multiplelines
Out[68]:
'one\ntwo\nthree'
In [69]:
print(multiplelines)
one
two
three
In [70]:
empty = ""
In [71]:
empty
Out[71]:
''
In [72]:
print(empty)

Higher level datatypes

lists

In [73]:
numbers = [1, 2, 3, 5, 8, 13]
In [74]:
nums = [12,13,14,15,16,11]
In [80]:
numbers[0] # zeroth item
Out[80]:
1
In [81]:
numbers[1] # 1st item
Out[81]:
2
In [77]:
numbers[3]
Out[77]:
5
In [79]:
numbers[-1] # last item
Out[79]:
13
In [83]:
numbers[-2] # second last
Out[83]:
8
In [84]:
s = ['p','y','t','h','o','n']
In [85]:
s
Out[85]:
['p', 'y', 't', 'h', 'o', 'n']
In [86]:
s[0]
Out[86]:
'p'
In [87]:
s[-1]
Out[87]:
'n'
In [88]:
name = "arcesium"
In [89]:
name[0]
Out[89]:
'a'
In [90]:
name[-1]
Out[90]:
'm'

indexing pattern for strings and lists

->  0  1  2  3  4  5
    P  Y  T  H  O  N
   -6 -5 -4 -3 -2 -1   <--
In [91]:
pre = "Hello"
post = "World"
In [92]:
"hello""world"
Out[92]:
'helloworld'
In [93]:
pre post
  File "<ipython-input-93-43e51bff3b58>", line 1
    pre post
           ^
SyntaxError: invalid syntax
In [94]:
pre, post
Out[94]:
('Hello', 'World')
In [95]:
pre + post
Out[95]:
'HelloWorld'
In [96]:
ones = [1,1,1,1,1]
In [97]:
ones * 2
Out[97]:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
In [98]:
ones + nums
Out[98]:
[1, 1, 1, 1, 1, 12, 13, 14, 15, 16, 11]
In [99]:
table = [ones, ones, ones]
In [101]:
table
Out[101]:
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
In [102]:
s
Out[102]:
['p', 'y', 't', 'h', 'o', 'n']
In [103]:
table = [ones, s, ones, s]
In [104]:
table
Out[104]:
[[1, 1, 1, 1, 1],
 ['p', 'y', 't', 'h', 'o', 'n'],
 [1, 1, 1, 1, 1],
 ['p', 'y', 't', 'h', 'o', 'n']]
In [105]:
table[0]
Out[105]:
[1, 1, 1, 1, 1]
In [106]:
table[-1]
Out[106]:
['p', 'y', 't', 'h', 'o', 'n']
In [107]:
s
Out[107]:
['p', 'y', 't', 'h', 'o', 'n']
In [109]:
p  = "python"
In [110]:
s[0]
Out[110]:
'p'
In [111]:
p[0]
Out[111]:
'p'
In [112]:
p[-1]
Out[112]:
'n'
In [113]:
s[-1]
Out[113]:
'n'
In [114]:
s
Out[114]:
['p', 'y', 't', 'h', 'o', 'n']
In [115]:
p
Out[115]:
'python'

dictionary

In [116]:
person = {"name":"Alice", "age":14, "email":"alice@wonder.land"}
In [118]:
bse_sheet = [["company","ticker","value"],["Hindustan Computers","hcl",400.0],["Tata Motors","tata",80.3]]
nse_sheet = [["company","ticker","value"],["Hindustan Computers","hcl",500.0],["Tata Motors","tata",75.3]]
In [119]:
stocks = {"bse":bse_sheet, "nse":nse_sheet}
In [120]:
person['email']
Out[120]:
'alice@wonder.land'
In [121]:
stocks['bse']
Out[121]:
[['company', 'ticker', 'value'],
 ['Hindustan Computers', 'hcl', 400.0],
 ['Tata Motors', 'tata', 80.3]]
In [122]:
person['name']
Out[122]:
'Alice'
In [123]:
person['age']
Out[123]:
14
In [124]:
a  = 10
In [125]:
numbers = [a, 2*a, 3*a, 4*a, 5*a, 6*a, a*(a+1)]
In [126]:
numbers
Out[126]:
[10, 20, 30, 40, 50, 60, 110]
In [127]:
person[0]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-127-d40e6f33acad> in <module>
----> 1 person[0]

KeyError: 0
In [128]:
person['email']
Out[128]:
'alice@wonder.land'
In [129]:
stocks['bse'][1] # get 1st row from bse sheet 
Out[129]:
['Hindustan Computers', 'hcl', 400.0]
In [131]:
stocks['bse'][1][1] # get 1st item from 1st row of bse sheet
Out[131]:
'hcl'

tuples

In [132]:
nums = [1, 1, 1, 1, 0]
In [133]:
nums
Out[133]:
[1, 1, 1, 1, 0]
In [134]:
nums1 = (1, 1, 1, 1)
In [135]:
nums[0] = 0
In [136]:
nums
Out[136]:
[0, 1, 1, 1, 0]
In [137]:
nums1[0] = 0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-137-10824205d205> in <module>
----> 1 nums1[0] = 0

TypeError: 'tuple' object does not support item assignment
In [138]:
nums1
Out[138]:
(1, 1, 1, 1)

tuples are similar to lists in all way except that they are immutable (means can not be changed once created)

In [139]:
nums1[0]
Out[139]:
1
In [140]:
nums1[-1]
Out[140]:
1
In [141]:
a = 5
b = 3
In [142]:
a,b
Out[142]:
(5, 3)
In [143]:
x = a,b
In [144]:
x
Out[144]:
(5, 3)

Multiple assignments

In [146]:
x, y = 2,3
In [147]:
x
Out[147]:
2
In [148]:
y
Out[148]:
3
In [149]:
y,x = x,y
In [150]:
x
Out[150]:
3
In [151]:
y
Out[151]:
2

set

In [152]:
{1, 1, 1, 2, 3, 2, 1, 3}
Out[152]:
{1, 2, 3}
In [153]:
s = {1, 1, 1, 2, 3, 2, 1, 3}
In [154]:
s
Out[154]:
{1, 2, 3}
In [155]:
s[0]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-155-c9c96910e542> in <module>
----> 1 s[0]

TypeError: 'set' object does not support indexing
In [ ]:
 

boolean

In [ ]:
 
In [158]:
2 in s # is 2 in set s?
Out[158]:
True
In [159]:
5 in s # is 5 in set s?
Out[159]:
False
In [160]:
x
Out[160]:
3
In [161]:
y
Out[161]:
2
In [163]:
x == y # check if x is equal to y?
Out[163]:
False
In [164]:
x != y # check if x is not equal to y?
Out[164]:
True
In [165]:
x is 3
Out[165]:
True
In [166]:
x is not 3
Out[166]:
False
In [167]:
"email" in person
Out[167]:
True
In [168]:
"address" in person
Out[168]:
False
In [169]:
person
Out[169]:
{'name': 'Alice', 'age': 14, 'email': 'alice@wonder.land'}
In [170]:
person['email'] == "alice@wonder.land"
Out[170]:
True
In [171]:
nums
Out[171]:
[0, 1, 1, 1, 0]
In [172]:
1 in nums
Out[172]:
True
In [173]:
5 in nums
Out[173]:
False

nothing

In [174]:
emptydict = {}
In [175]:
type(emptydict)
Out[175]:
dict
In [176]:
emptylist = []
In [177]:
emptystring = ""
In [178]:
nothing = None
In [179]:
nothing
In [180]:
print(nothing)
None

Functions

In [181]:
print(nothing)
None
In [182]:
print(1,2,3)
1 2 3
In [183]:
len(nums)
Out[183]:
5
In [184]:
nums
Out[184]:
[0, 1, 1, 1, 0]
In [185]:
language = "Python"
In [187]:
len(language)
Out[187]:
6
In [188]:
len(person)
Out[188]:
3
In [189]:
person
Out[189]:
{'name': 'Alice', 'age': 14, 'email': 'alice@wonder.land'}
In [190]:
primes = {2,3,5,7,11,13}
In [191]:
len(primes)
Out[191]:
6
In [192]:
6 in primes
Out[192]:
False
In [193]:
t = (1,2,3,4,5,6)
In [194]:
len(t)
Out[194]:
6
In [195]:
len(person['name'])
Out[195]:
5
In [197]:
int("2")
Out[197]:
2
In [198]:
int("23232343235435")
Out[198]:
23232343235435
In [199]:
float("2.4")
Out[199]:
2.4
In [200]:
str(545)
Out[200]:
'545'
In [201]:
str([1,2,3,4])
Out[201]:
'[1, 2, 3, 4]'
In [202]:
str("3.45")
Out[202]:
'3.45'
In [203]:
sf = "4.5"
In [204]:
sf + 5.6
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-204-162e97a20a4e> in <module>
----> 1 sf + 5.6

TypeError: can only concatenate str (not "float") to str
In [205]:
float(sf)   + 5.6
Out[205]:
10.1
In [206]:
sf + str(5.6)
Out[206]:
'4.55.6'

probems

  • Find number of digits in 2**100
In [207]:
2**100
Out[207]:
1267650600228229401496703205376
In [209]:
s = str(2**100)
In [210]:
s
Out[210]:
'1267650600228229401496703205376'
In [211]:
len(s)
Out[211]:
31
In [212]:
len(str(2**100)) # inner function will be called first , then outer
Out[212]:
31
In [213]:
sum([1, 2, 3, 4])
Out[213]:
10
In [214]:
list("python")
Out[214]:
['p', 'y', 't', 'h', 'o', 'n']
In [215]:
list((2,3,4,5))
Out[215]:
[2, 3, 4, 5]
In [216]:
nums
Out[216]:
[0, 1, 1, 1, 0]
In [217]:
t
Out[217]:
(1, 2, 3, 4, 5, 6)
In [218]:
list(t)
Out[218]:
[1, 2, 3, 4, 5, 6]
In [219]:
t
Out[219]:
(1, 2, 3, 4, 5, 6)
In [220]:
numbers = [1,2,3,4,5,6,7]
In [221]:
range(10)
Out[221]:
range(0, 10)
In [222]:
list(range(10))
Out[222]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [223]:
dict([("x",1),("y",2)])
Out[223]:
{'x': 1, 'y': 2}
In [227]:
list(range(5))
Out[227]:
[0, 1, 2, 3, 4]
In [228]:
list(range(5,20))
Out[228]:
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
In [229]:
list(range(5,20,3))
Out[229]:
[5, 8, 11, 14, 17]
In [230]:
d = dict([("x",1),("y",2)])
In [231]:
d['x']
Out[231]:
1

Question

when to use which bracket? All kinds of access is thorugh []

In [232]:
items = list(range(5))
In [233]:
items[0]
Out[233]:
0
In [234]:
person['name']
Out[234]:
'Alice'
In [235]:
t
Out[235]:
(1, 2, 3, 4, 5, 6)
In [236]:
t[0]
Out[236]:
1

While creating lists , we use square bracket[]

In [237]:
l = [1,1,0,0,1]

While creating dictionary , we use {}

In [238]:
d = {"one":1,
     "two":2,
     "three":3,
     "four":4
    }
In [239]:
d
Out[239]:
{'one': 1, 'two': 2, 'three': 3, 'four': 4}
In [240]:
d['one'] # access is square bracket
Out[240]:
1

While creating set , we use {}

In [241]:
s = {1,2,3,4}

While creating tuple , we use ()

In [242]:
t = (1,2,2,1,1)
In [243]:
special = (1,)
In [244]:
special
Out[244]:
(1,)
In [245]:
len(special)
Out[245]:
1

While calling functions, we use () after function name

In [246]:
len(special)
Out[246]:
1
In [247]:
len(d)
Out[247]:
4

Custom functions

In [249]:
# defining a function
def add(a, b):
    c = a + b
    return c
In [250]:
x
Out[250]:
3
In [251]:
x
Out[251]:
3
In [252]:
add
Out[252]:
<function __main__.add(a, b)>
In [253]:
add(5,6)
Out[253]:
11
In [254]:
x
Out[254]:
3
In [255]:
x = add(5,6)
In [256]:
def sumofsquares(a, b):
    sa  = a*a
    sb = b*b
    return sa + sb
In [257]:
def sumofsquares1(a, b):
    return a**2 + b **2
In [258]:
sumofsquares
Out[258]:
<function __main__.sumofsquares(a, b)>
In [259]:
sumofsquares1
Out[259]:
<function __main__.sumofsquares1(a, b)>
In [260]:
sumofsquares(3,4)
Out[260]:
25
In [261]:
def len(x):
    return 5
In [262]:
len(person)
Out[262]:
5
In [263]:
len([1,2,3,4,5,6,7,8,9])
Out[263]:
5
In [264]:
del len
In [265]:
len(person)
Out[265]:
3
In [267]:
def len_(x):
    return 5
In [268]:
len(person)
Out[268]:
3
In [269]:
len_(34)
Out[269]:
5
In [270]:
def squareroot(x):
    return x**(1/2)
In [271]:
def genericroot(x, r):
    return x**(1/r)
In [272]:
genericroot(4,2)
Out[272]:
2.0
In [273]:
squareroot(4)
Out[273]:
2.0

problems

  • Write a function count_digits which will take integer as an argument and return number of digits in that integer
    >>> count_digits(1000)
    4
    >>> count_digits(2**100)
    31
In [274]:
def count_digits(n):
    return len(str(n))
In [275]:
count_digits(2**100)
Out[275]:
31
In [276]:
def square(x):
    return x*x
In [277]:
def square1(x):
    print(x*x)
In [278]:
square(5)
Out[278]:
25
In [279]:
square1(5)
25
In [280]:
square(square(5))
Out[280]:
625
In [281]:
square1(square1(5))
25
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-281-58f9019432eb> in <module>
----> 1 square1(square1(5))

<ipython-input-277-dfbe86f79a52> in square1(x)
      1 def square1(x):
----> 2     print(x*x)

TypeError: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
In [282]:
def func():
    pass
In [283]:
func()
In [284]:
r = func()
In [285]:
print(r)
None
In [286]:
print(square(5))
25

More about functions

In [287]:
def add(x,y):
    return x+y
In [288]:
add
Out[288]:
<function __main__.add(x, y)>
In [289]:
f = add
In [290]:
print(f)
<function add at 0x7f733068ad08>
In [291]:
print(add)
<function add at 0x7f733068ad08>
In [292]:
add(3,4)
Out[292]:
7
In [293]:
f(3,4)
Out[293]:
7
In [294]:
def sumofsquares(a, b):
    return sqauare(a) + square(b)


def cube(x):
    return x*x*x

def sumofcubes(a,b):
    return cube(a) + cube(b)
In [295]:
def sumof(a, b, f):
    return f(a) + f(b)
In [296]:
sumof(3, 4, square)
Out[296]:
25
In [297]:
sumof(3, 4, cube)
Out[297]:
91
In [298]:
sumofcubes(3, 4)
Out[298]:
91
In [299]:
max([23,23,1,2,23,12,45,67,34])
Out[299]:
67
In [300]:
words = ["one","two", "three","four","five"]
In [301]:
max(words)
Out[301]:
'two'
In [302]:
max(words, key=len)
Out[302]:
'three'
In [308]:
stocks = [
    ("Infosys",        'infy', 1500.4, 50),
    ('Tata Motors',    'tata', 203.5,  3.0),
    ('Capgemini',      'cpgm', 500.0, 15.0),
    ('Spotyfy',        'sptf', 1600.0, -20.0),
    ('Simple Solutions','sls', 1200.0, 10.0)
]
In [309]:
max(stocks)
Out[309]:
('Tata Motors', 'tata', 203.5, 3.0)
In [310]:
def get_stockvalue(row):
    return row[2]

def get_gain(row):
    return row[3]

max(stocks, key=get_stockvalue)
Out[310]:
('Spotyfy', 'sptf', 1600.0, -20.0)
In [311]:
max(stocks, key=get_gain)
Out[311]:
('Infosys', 'infy', 1500.4, 50)
In [312]:
min(stocks, key=get_gain)
Out[312]:
('Spotyfy', 'sptf', 1600.0, -20.0)
In [313]:
min(stocks, key=get_stockvalue)
Out[313]:
('Tata Motors', 'tata', 203.5, 3.0)
In [314]:
help(filter)
Help on class filter in module builtins:

class filter(object)
 |  filter(function or None, iterable) --> filter object
 |  
 |  Return an iterator yielding those items of iterable for which function(item)
 |  is true. If function is None, return the items that are true.
 |  
 |  Methods defined here:
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __next__(self, /)
 |      Implement next(self).
 |  
 |  __reduce__(...)
 |      Return state information for pickling.
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.

In [315]:
def greater_than1000(row):
    return row[2]>1000
In [316]:
2 > 3
Out[316]:
False
In [317]:
2 >= 2
Out[317]:
True
In [319]:
list(filter(greater_than1000, stocks))
Out[319]:
[('Infosys', 'infy', 1500.4, 50),
 ('Spotyfy', 'sptf', 1600.0, -20.0),
 ('Simple Solutions', 'sls', 1200.0, 10.0)]
In [320]:
sorted(words)
Out[320]:
['five', 'four', 'one', 'three', 'two']
In [321]:
words
Out[321]:
['one', 'two', 'three', 'four', 'five']
In [322]:
sorted(words, reverse=True)
Out[322]:
['two', 'three', 'one', 'four', 'five']
In [323]:
sorted(words, key=len, reverse=True)
Out[323]:
['three', 'four', 'five', 'one', 'two']
In [324]:
sorted(words, key=len)
Out[324]:
['one', 'two', 'four', 'five', 'three']
In [ ]: