10 Python Interview Questions You need to know

Python is very popular programming language with many job offers. I collected some questions (with answers) from many students interviews. Test yourself: are you ready to work with python?

1. Base and derived classes:

Look at the following code:

class A(object):
    def show(self):
        print 'base show'

class B(A):
    def show(self):
        print 'derived show'

obj = B()
obj.show()

Is it possible to make obj call the base class show? In other words I want to cast obj to type A

Answer:

obj.__class__ = A
obj.show() 

The __class__ attribute points to the class object, just change it to point to A and call the function,  don’t forget to change it back!!!

 

2. Function Object

What do you need to add to make this code run, i.e. use object as a function:

class A(object):
    def __init__(self,a,b):
        self.__a = a
        self.__b = b
    def myprint(self):
        print 'a=', self.__a, 'b=', self.__b
    

a1=A(10,20)
a1.myprint()

a1(80)

 

 

Answer:

To make an object callable, implement __call__ method:

class A(object):
    def __init__(self, a, b):
        self.__a = a
        self.__b = b
    def myprint(self):
        print 'a=', self.__a, 'b=', self.__b
    def __call__(self, num):
        print 'call:', num + self.__a

 

3. New and Init

What will be printed:

class B(object):
    def fn(self):
        print 'B fn'
    def __init__(self):
        print "B INIT"


class A(object):
    def fn(self):
        print 'A fn'

    def __new__(cls,a):
            print "NEW", a
            if a>10:
                return super(A, cls).__new__(cls)
            return B()

    def __init__(self,a):
        print "INIT", a

a1 = A(5)
a1.fn()
a2=A(20)
a2.fn()

 

 

Answer:

NEW 5
B INIT
B fn
NEW 20
INIT 20
A fn

In __new__ you can decide which object to return – use it as a factory , the  __init__ function is called on the created object class

 

4. Python Collections Comprehension

What will be printed

ls = [1,2,3,4]
list1 = [i for i in ls if i>2]
print list1

list2 = [i*2 for i in ls if i>2]
print list2

dic1 = {x: x**2 for x in (2, 4, 6)}
print dic1

dic2 = {x: 'item' + str(x**2) for x in (2, 4, 6)}
print dic2

set1 = {x for x in 'hello world' if x not in 'low level'}
print set1

 

 

Answer:

[3, 4]  
[6, 8]
{2: 4, 4: 16, 6: 36}
{2: 'item4', 4: 'item16', 6: 'item36'}
set(['h', 'r', 'd'])

All the above statements build and return a collection based on another.

 

5. Globals and locals

What is the output of the following code:

num = 9

def f1():
    num = 20

def f2():
    print num


f2()
f1()
f2()

 

Answer:

9
9

num is not a global variable so each function gets its own copy, what do you need to add to make it work as a global variable?

 

Answer:

num = 9

def f1():
    global num
    num = 20

def f2():
   print num

f2()
f1()
f2()

# prints:
#      9
#      20

 

6. Swap numbers

a=8
b=9

Swap a and b in one line

 

Answer:

(a,b) = (b,a)

 

7. Default method

Look at the following code:

class A(object):
    def __init__(self,a,b):
        self.a1 = a
        self.b1 = b
        print 'init'
    def mydefault(self):
        print 'default'

a1 = A(10,20)
a1.fn1()
a1.fn2()
a1.fn3()

fn1,fn2,fn3 are not declared, add the code to make any undeclared function to be replaced with mydefault, i.e. the above code output is:

default
default
default

 

 

Answer:

class A(object):
    def __init__(self,a,b):
        self.a1 = a
        self.b1 = b
        print 'init'
    def mydefault(self):
        print 'default'
    def __getattr__(self,name):
        return self.mydefault

a1 = A(10,20)
a1.fn1()
a1.fn2()
a1.fn3()

The special method __getattr__ is invoked if an undeclared method is called. It returns the default function that replaces it. In this case the function is called without parameters but you can add *args to make it replace any function

class A(object):
    def __init__(self,a,b):
        self.a1 = a
        self.b1 = b
        print 'init'
    def mydefault(self,*args):
        print 'default:' + str(args[0])
    def __getattr__(self,name):
        print "other fn:",name
        return self.mydefault

a1 = A(10,20)
a1.fn1(33)
a1.fn2('hello')
a1.fn3(10)

 

8. Packages and modules

Given a package ‘demopack’ with 3 modules: mod1.py, mod2.py, mod3.py. What do you need to write to make the package exports only mod1,mod3 when using:

from demopack import *

 

Answer:

Add __init__.py to the package and add the following line:

__all__ = ['mod1','mod3']

 

9. Closure

Write a function ‘mulby’ that gets an integer parameter n and returns a function that multiplies its input by n

 

Answer:

def mulby(num):
    def gn(val):
        return num * val

    return gn


zw = mulby(7)
print(zw(9));

 

10. Performance

Explain why this code is slow:

def strtest1(num):
        str='first'
        for i in range(num):
            str+="X"
        return str

 

Answer:

Python strings are immutable, on each iteration the a new string is created. Calling the function with num=500 it will create 500 different strings with len ranging from 5 to 505 and cost at about 25000 characters – 50kb of memory for 505 characters string as a result

 

See here good introduction to machine learning

 

Tagged

8 thoughts on “10 Python Interview Questions You need to know

  1. These questions and answers are what I call “python trivia”. Don’t get me wrong – none of these things are wrong. Nor am I saying that something like these question won’t come up in some interview. Furthermore, the list of python trivia could go on and on. What I am saying is that I think these questions are the wrong way to think about python.
    Where I tend to get stuck in python is getting a good design. I’d like to be able to measure the complexity of several designs, pick the least complicated design and then go from that design to working code. In other words, I want to think strategically, not tactically.

    Question 10 is very important. A good follow up question would be “How to make this go faster?”. My answer would be to make str a list of strings and then join the elements before returning.

  2. Last one is really tricky. Mutable and immutable behavior of Python data values should be learn as it is more related to memory management. But, many of the Python beginners miss it.

  3. str=’first{}’.format(‘X’*num)

    1. simple concatination is little bit faster than str.format method
      from timeit import timeit
      >>> timeit(”'”first” + “X”*1000”’)
      0.320526123046875
      >>> timeit(”'”first” + “X”*10000”’)
      0.6229779720306396
      >>> timeit(”'”first{}”.format(“X”*1000)”’)
      0.5572819709777832
      >>> timeit(”'”first{}”.format(“X”*10000)”’)
      0.9632759094238281

  4. I agree with the first commenter (Jeff). Except the 10th question which is really something any candidate should understand (and to generalize, candidates should be at ease with CS theory, complexity, datastructures, etc…), the rest is implementation details (that seasoned python programmers usually knows, but by testing implementation details in interviews, you’ll pass on good candidates and hire the fans of ugly hacks).

    About question 1, the answer is really bad style, IMHO, and can lead to problems if used (what about concurrency? what about exceptions raised? what about recursive calls or usage of self in the method?).

    Instead, I’d suggest to statically call the base class method providing the “self” instance of the subclass:

    >>> A.show(obj)

    Or at least, wrap it in a try/finally block.
    But in real life, if you want to use a “A”, you usually create a “A”.

  5. “obj.__class__ = A
    obj.show()”

    That’s hilarious!))
    Have you ever heard of “super()” calls?

  6. The last question is a nasty ancient myth. This code was slow on very old (2.5 and earlier, AFAIK) versions of python, but it is not anymore. Now python check string reference count on += and if it equals to 1 – string is modified in place. So the given code is as fast as “”.join(..).

    In [1]: def strtest1(num):
    …: str = ‘first’
    …: for i in range(num):
    …: str += “X”
    …: return str

    In [3]: def strtest2(num):
    …: str = [‘first’]
    …: for i in range(num):
    …: str.append(“X”)
    …: return “”.join(str)

    In [2]: %timeit strtest1(100000) # 100k
    6.47 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

    In [4]: %timeit strtest2(100000) # 100k
    6.12 ms ± 79.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

    In [11]: %timeit strtest1(1000000) # 1m
    63.8 ms ± 320 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

    In [12]: %timeit strtest2(1000000) # 1m
    63.2 ms ± 1.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

    They both has O(n) and almost the same speed (+-3%)

    BTW – don’t call variable ‘str’, it’s name of built-in type, and put spaces around operators, please

Comments are closed.