Are you trying for a Python job? Here are the top frequently asked interview questions and answers to step-on the python interview. Dive into these Python interview questions and answers and see just how well-versed you are in this Python language.
Ans: Python is a high-level, interpreted, interactive and object-oriented scripting language. Python is designed to be highly readable. It uses English keywords frequently where as other languages use punctuation, and it h
as fewer syntactical constructions than other languages.
Ans: Following are some of the salient features of python
Ans:This shows that you are willing to do more than the bare minimum in terms of keeping your skillset up to date. If you work on personal projects and code outside of the workplace then employers are more likely to see you as an asset that will grow. Even if they don't ask this question I find it's useful to broach the subject.
Ans: Yes! Python is a case sensitive programming language.
What are the supported data types in Python?
Python has five standard data types −
Ans: It will print complete string. Output would be Hello World!.
Ans: It will print first character of the string. Output would be H.
Ans: It will print characters starting from 3rd to 5th. Output would be llo.
Ans: It will print characters starting from 3rd character. Output would be llo World!.
Ans: It will print string two times. Output would be Hello World!Hello World!.
Ans: It will print concatenated string. Output would be Hello World!TEST.
Ans: It will print concatenated lists. Output would be [ 'abcd', 786 , 2.23, 'john', 70.2 ].
Q12. What is the output of print list[0] if list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]?
Ans: It will print first element of the list. Output would be abcd.
Ans: It will print elements starting from 2nd till 3rd. Output would be [786, 2.23].
Ans: It will print elements starting from 3rd element. Output would be [2.23, 'john', 70.200000000000003].
Ans: It will print list two times. Output would be [123, 'john', 123, 'john'].
Ans: It will print concatenated lists. Output would be ['abcd', 786, 2.23, 'john', 70.2, 123, 'john', 123, 'john'].
Ans: A tuple is another sequence data type that is similar to the list. A tuple consists of a number of values separated by commas. Unlike lists, however, tuples are enclosed within parentheses.
Ans: The main differences between lists and tuples are − Lists are enclosed in brackets ( [ ] ) and their elements and size can be changed, while tuples are enclosed in parentheses ( ( ) ) and cannot be updated. Tuples can be thought of as read-only lists.
Ans: It will print complete tuple. Output would be ('abcd', 786, 2.23, 'john', 70.200000000000003).
Ans: It will print first element of the tuple. Output would be abcd.
Ans: It will print elements starting from 2nd till 3rd. Output would be (786, 2.23).
Ans: It will print elements starting from 3rd element. Output would be (2.23, 'john', 70.200000000000003).
Ans: It will print tuple two times. Output would be (123, 'john', 123, 'john').
Ans: It will print concatenated tuples. Output would be ('abcd', 786, 2.23, 'john', 70.200000000000003, 123, 'john').
Ans: Python's dictionaries are kind of hash table type. They work like associative arrays or hashes found in Perl and consist of key-value pairs. A dictionary key can be almost any Python type, but are usually numbers or strings. Values, on the other hand, can be any arbitrary Python object.
Ans: Dictionaries are enclosed by curly braces ({ }) and values can be assigned and accessed using square braces ([]).
dict = {}
dict['one'] = "This is one"
dict[2] = "This is two"
tinydict = {'name': 'john','code':6734, 'dept': 'sales'}
Ans: Using dictionary.keys() function, we can get all the keys from the dictionary object.
print dict.keys() # Prints all the keys
Ans: Using dictionary.values() function, we can get all the values from the dictionary object.
print dict.values() # Prints all the values
Ans: int(x [,base]) - Converts x to an integer. base specifies the base if x is a string.
Ans: long(x [,base] ) - Converts x to a long integer. base specifies the base if x is a string.
Ans: float(x) − Converts x to a floating-point number.
Ans: str(x) − Converts object x to a string representation.
Ans: repr(x) − Converts object x to an expression string.
Ans: eval(str) − Evaluates a string and returns an object.
Ans: tuple(s) − Converts s to a tuple.
Ans: list(s) − Converts s to a list.
Ans: set(s) − Converts s to a set.
Ans: dict(d) − Creates a dictionary. d must be a sequence of (key,value) tuples.
Ans: frozenset(s) − Converts s to a frozen set.
Ans: chr(x) − Converts an integer to a character.
Ans: unichr(x) − Converts an integer to a Unicode character.
Ans: ord(x) − Converts a single character to its integer value.
Ans: hex(x) − Converts an integer to a hexadecimal string.
Ans: oct(x) − Converts an integer to an octal string.
Ans: ** Exponent − Performs exponential (power) calculation on operators. a**b = 10 to the power 20 if a = 10 and b = 20.
Ans: // Floor Division − The division of operands where the result is the quotient in which the digits after the decimal point are removed.
Ans: is − Evaluates to true if the variables on either side of the operator point to the same object and false otherwise. x is y, here is results in 1 if id(x) equals id(y).
Ans: not in − Evaluates to true if it does not finds a variable in the specified sequence and false otherwise. x not in y, here not in results in a 1 if x is not a member of sequence y.
Ans: break statement − Terminates the loop statement and transfers execution to the statement immediately following the loop.
Ans: Continue statement − Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.
Ans: pass statement − The pass statement in Python is used when a statement is required syntactically but you do not want any command or code to execute.
Ans: choice(seq) − Returns a random item from a list, tuple, or string.
Ans: randrange ([start,] stop [,step]) − returns a randomly selected element from range(start, stop, step).
Ans: random() − returns a random float r, such that 0 is less than or equal to r and r is less than 1.
Ans: seed([x]) − Sets the integer starting value used in generating random numbers. Call this function before calling any other random module function. Returns None.
Ans: shuffle(lst) − Randomizes the items of a list in place. Returns None.
Ans: capitalize() − Capitalizes first letter of string.
Ans: isalnum() − Returns true if string has at least 1 character and all characters are alphanumeric and false otherwise.
Ans: isdigit() − Returns true if string contains only digits and false otherwise.
Ans: islower() − Returns true if string has at least 1 cased character and all cased characters are in lowercase and false otherwise.
Ans: isnumeric() − Returns true if a unicode string contains only numeric characters and false otherwise.
Ans: isspace() − Returns true if string contains only whitespace characters and false otherwise.
Ans: istitle() − Returns true if string is properly "titlecased" and false otherwise.
Ans: isupper() − Returns true if string has at least one cased character and all cased characters are in uppercase and false otherwise.
Ans: join(seq) − Merges (concatenates) the string representations of elements in sequence seq into a string, with separator string.
Ans: len(string) − Returns the length of the string.
Ans: just(width[, fillchar]) − Returns a space-padded string with the original string left-justified to a total of width columns.
Ans: lower() − Converts all uppercase letters in string to lowercase.
Ans: strip() − Removes all leading whitespace in string.
Ans: max(str) − Returns the max alphabetical character from the string str.
Ans: min(str) − Returns the min alphabetical character from the string str.
Ans: replace(old, new [, max]) − Replaces all occurrences of old in string with new or at most max occurrences if max given.
Ans: strip([chars]) − Performs both lstrip() and rstrip() on string.
Ans: swapcase() − Inverts case for all letters in string.
Ans: title() − Returns "titlecased" version of string, that is, all words begin with uppercase and the rest are lowercase.
Ans: upper() − Converts all lowercase letters in string to uppercase.
Ans: isdecimal() − Returns true if a unicode string contains only decimal characters and false otherwise.
Ans: To remove a list element, you can use either the del statement if you know exactly which element(s) you are deleting or the remove() method if you do not know.
Ans: 3.
Ans: [1, 2, 3, 4, 5, 6]
Ans: ['Hi!', 'Hi!', 'Hi!', 'Hi!']
Ans: True
Ans: 1 2 3
Ans: 3, Offsets start at zero.
Ans: L[-1] = 3, L[-2]=2, L[-3]=1
Ans: 2, 3, Slicing fetches sections.
Ans: cmp(list1, list2) − Compares elements of both lists.
Ans: len(list) − Gives the total length of the list.
Ans: max(list) − Returns item from the list with max value.
Ans: min(list) − Returns item from the list with min value.
Ans: list.index(obj) − Returns the lowest index in list that obj appears.
Ans: list.insert(index, obj) − Inserts object obj into list at offset index.
Ans: list.pop(obj=list[-1]) − Removes and returns last object or obj from list.
Ans: list.remove(obj) − Removes object obj from list.
Ans: list.reverse() − Reverses objects of list in place.
Ans: list.sort([func]) − Sorts objects of list, use compare func if given.
Ans:
datetime (used to manipulate date and time)
re (regular expressions)
urllib, urllib2 (handles many HTTP things)
string (a collection of different groups of strings for example all lower_case letters etc)
itertools (permutations, combinations and other useful iterables)
ctypes (from python docs: create and manipulate C data types in Python)
email (from python docs: A package for parsing, handling, and generating email messages)
__future__ (Record of incompatible language changes. like division operator is different and much better when imported from __future__)
sqlite3 (handles database of SQLite type)
unittest (from python docs: Python unit testing framework, based on Erich Gamma’s JUnit and Kent Beck’s Smalltalk testing framework)
xml (xml support)
logging (defines logger classes. enables python to log details on severity level basis)
os (operating system support)
pickle (similar to json. can put any data structure to external files)
subprocess (from docs: This module allows you to spawn processes, connect to their input/output/error pipes, and obtain their return codes)
webbrowser (from docs: Interfaces for launching and remotely controlling Web browsers.)
traceback (Extract, format and print Python stack traces)
Ans: mechanize
django
gtk
A lot of other can be found at pypi.
Ans: It declares that the given directory is a package. #Python Docs (From Endophage‘s comment)
Ans: pass does nothing. It is used for completing the code where we need something. For eg:
1
2 |
class abc():
pass |
Ans: docstring is the documentation string for a function. It can be accessed by
function_name.__doc__
it is declared as:
1
2 |
def function_name():
"""your docstring""" |
Writing documentation for your progams is a good habit and makes the code more understandable and reusable.
Ans: Creating a list by doing some operation over data that can be accessed using an iterator. For eg:
1
2 3 |
>>>[ord(i) for i in string.ascii_uppercase]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90] >>> |
Ans: map executes the function given as the first argument on all the elements of the iterable given as the second argument. If the function given takes in more than 1 arguments, then many iterables are given. #Follow the link to know more similar functions
For eg:
1
2 3 4 5 |
>>>a='ayush'
>>>map(ord,a) .... [97, 121, 117, 115, 104] >>> print map(lambda x, y: x*y**2, [1, 2, 3], [2, 4, 1]) .... [4, 32, 3] |
1
2 3 4 5 6 7 8 9 10 11 |
Help on built-in function map in module __builtin__:
map(...) map(function, sequence[, sequence, ...]) -> list Return a list of the results of applying the function to the items of the argument sequence(s). If more than one sequence is given, the function is called with an argument list consisting of the corresponding item of each sequence, substituting None for missing values when not all sequences have the same length. If the function is None, return a list of the items of the sequence (or a list of tuples if more than one sequence). |
#Python Docs
Ans: A tuple is immutable i.e. can not be changed. It can be operated on only. But a list is mutable. Changes can be done internally to it.
tuple initialization: a = (2,4,5)
list initialization: a = [2,4,5]
The methods/functions provided with each types are also different. Check them out yourself.
Ans:
1
2 |
a = ['one', 'two', 'three']
Ans: ", ".join(a) |
1
2 3 4 5 6 |
>>>help(str.join)
Help on method_descriptor: join(...) S.join(iterable) -> string Return a string which is the concatenation of the strings in the iterable. The separator between elements is S. |
1
2 |
word = 'abcdefghij'
print word[:3] + word[3:] |
Ans: ‘abcdefghij’ will be printed.
This is called string slicing. Since here the indices of the two slices are colliding, the string slices are ‘abc’ and ‘defghij’. The ‘+’ operator on strings concatenates them. Thus, the two slices formed are concatenated to give the answer ‘abcdefghij’.
1
2 |
word = 'word'
print word.__len__() |
Ans:
1
2 |
word = 'word'
print len(word) |
Ans:
1
2 3 4 5 |
try:
with open('filename','r') as f: print f.read() except IOError: print "no such file exists" |
1
2 3 4 |
a = 1
a, b = a+1, a+1 print a print b |
Ans:
2
2
The second line is a simultaneous declaration i.e. value of new a is not used when doing b=a+1.
This is why, exchanging numbers is as easy as:
1 | a,b = b,a |
All the elements should be unique
words = [‘one’, ‘one’, ‘two’, ‘three’, ‘three’, ‘two’]
Ans: A bad solution would be to iterate over the list and checking for copies somehow and then remove them!
One of the best solutions I can think of right now:
1
2 |
a = [1,2,2,3]
list(set(a)) |
set is another type available in python, where copies are not allowed. It also has some good functions available used in set operations ( like union, difference ).
{‘one’:2, ‘two’:2, ‘three’:2}
Ans:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
>>> def dic(words):
a = {} for i in words: try: a[i] += 1 except KeyError: ## the famous pythonic way: a[i] = 1 ## Halt and catch fire return a
>>> a='1,3,2,4,5,3,2,1,4,3,2'.split(',') >>> a ['1', '3', '2', '4', '5', '3', '2', '1', '4', '3', '2'] >>> dic(a) {'1': 2, '3': 3, '2': 3, '5': 1, '4': 2} |
Without using try-catch block:
1
2 3 4 5 6 7 8 9 10 |
>>> def dic(words):
data = {} for i in words: data[i] = data.get(i, 0) + 1 return data
>>> a ['1', '3', '2', '4', '5', '3', '2', '1', '4', '3', '2'] >>> dic(a) {'1': 2, '3': 3, '2': 3, '5': 1, '4': 2} |
PS: Since the collections module (which gives you the defaultdict) is written in python, I would not recommend using it. The normal dict implementation is in C, it should be much faster. You can use timeit module to check for comparing the two.
So, David and I have saved you the work to check it. Check the files on github. Change the data file to test different data.
Ans: Can be checked by a single statement (pythonic beauty):
1
2 3 4 5 6 7 8 |
print "The list is empty" if len(a)==0 else "The list is not empty"
>>> a='' >>> print "'The list is empty'" if len(a)==0 else "'The list is not empty'" 'The list is empty' >>> a='asd' >>> print "'The list is empty'" if len(a)==0 else "'The list is not empty'" 'The list is not empty' |
Ans:
1
2 3 4 |
try:
import mechanize as me except ImportError: import urllib as me |
## here you have atleast 1 module imported as me.
This is used to check if the users computer has third party libraries that we need. If not, we work with a default library of python. Quite useful in updating softwares.
PS: This is just one of the uses of try-except blocks. You can note a good use of these in API’s.
Also note that if we do not define the error to be matched, the except block would catch any error raised in try block.
Ans:
1
2 |
with open("filename.txt", "r") as f1:
print len(f1.readline().rstrip()) |
rstrip() is an inbuilt function which strips the string from the right end of spaces or tabs (whitespace characters).
Ans:
1 | print sum(range(1,101)) |
range() returns a list to the sum function containing all the numbers from 1 to 100. Please see that the range function does not include the end given (101 here).
1 | print sum(xrange(1, 101)) |
xrange() returns an iterator rather than a list which is less heavy on the memory.
num_strings = [‘1′,’21’,’53’,’84’,’50’,’66’,’7′,’38’,’9′]
Ans:
use a list comprehension
1
2 |
>>> [int(i) for i in num_strings]
[1, 21, 53, 84, 50, 66, 7, 38, 9] |
#num_strings should not contain any non-integer character else ValueError would be raised. A try-catch block can be used to notify the user of this.
Another one suggested by David using maps:
1
2 |
>>> map(int, num_strings)
[1, 21, 53, 84, 50, 66, 7, 38, 9] |
Ans:
1
2 3 4 5 6 7 |
>>> odd=[]
>>> even=[] >>> for i in n: even.append(i) if i%2==0 else odd.append(i)
## all odd numbers in list odd ## all even numbers in list even |
Though if only one of the lists were requires, using list comprehension we could make:
1
2 |
even = [i for i in num_strings if i%2==0]
odd = [i for i in num_strings if i%2==1] |
But using this approach if both lists are required would not be efficient since this would iterate the list two times.!
nums = [1,5,2,10,3,45,23,1,4,7,9]
Ans: nums.sort() # The lists have an inbuilt function, sort()
sorted(nums) # sorted() is one of the inbuilt functions)
Python uses TimSort for applying this function. Check the link to know more.
Ans:
1
2 3 4 5 6 7 8 9 |
>>> for index, data in enumerate(asd):
.... print "{0} -> {1}".format(index, data)
0 -> 4 1 -> 7 2 -> 3 3 -> 2 4 -> 5 5 -> 9 |
#OR
1
2 3 4 5 6 7 8 9 10 11 |
>>> asd = [4,7,3,2,5,9]
>>> for i in range(len(asd)): .... print i+1,'-->',asd[i]
1 --> 4 2 --> 7 3 --> 3 4 --> 2 5 --> 5 6 --> 9 |
Ans:
1
2 3 4 5 6 |
n = [1,2,5,10,3,100,9,24]
for e in n: if e<5: n.remove(e) print n |
## after e is removed, the index position gets disturbed. Instead it should be:
1
2 3 4 5 |
a=[]
for e in n: if e >= 5: a.append(e) n = a |
OR again a list comprehension:
1 | return [i for i in n if i >= 5] |
OR use filter
1 | return filter(lambda x: x >= 5, n) |
1
2 3 4 |
def func(x,*y,**z):
.... print z
func(1,2,3) |
Ans: Here the output is :
{} #Empty Dictionay
x is a normal value, so it takes 1..
y is a list of numbers, so it takes 2,3..
z wants named parameters, so it can not take any value here.
Thus the given answer.
Ans:
a = 5
b = 9
as i told earlier too, just use:
a,b = b,a
1
2 3 4 5 6 7 8 9 |
class C(object):
.... def__init__(self): .... self.x =1
c=C() print c.x print c.x print c.x print c.x |
Ans: All the outputs will be 1, since the value of the the object’s attribute(x) is never changed.
1
1
1
1
x is now a part of the public members of the class C.
Thus it can be accessed directly..
1
2 3 4 5 6 7 |
func([1,2,3]) # explicitly passing in a list
func() # using a default empty list
def func(n = []): #do something with n
print n |
Ans. This would result in a NameError. The variable n is local to function func and can’t be accessesd outside. So, printing it won’t be possible.
Edit: An extra point for interviews given by Shane Green and Peter: “””Another thing is that mutable types should never be used as default parameter values. Default parameter value expressions are only evaluated once, meaning every invocation of that method shares the same default value. If one invocation that ends up using the default value modifies that value–a list, in this case–it will forever be modified for all future invocations. So default parameter values should limited to primitives, strings, and tuples; no lists, dictionaries, or complex object instances.”””
Reference: Default argument values
Ans:
Ans: It is somewhat more complicated than I have written here (Thanks David for pointing). Explaining all here won’t be possible. Some good links that would really make you understand how things are:
s = ‘aaa bbb ccc ddd eee’
Ans:
1
2 |
''.join(s.split())
## join without spaces the string after splitting it |
OR
1 | filter(lambda x: x != ‘ ‘, s) |
s = a + ‘[‘ + b + ‘:’ + c + ‘]’
Ans: seems like a string is being concatenated. Nothing much can be said without knowing types of variables a, b, c. Also, if all of the a, b, c are not of type string, TypeError would be raised. This is because of the string constants (‘[‘ , ‘]’) used in the statement.
1
2 3 4 5 6 7 8 |
def append_s(words):
new_words=[] for word in words: new_words.append(word + 's') return new_words
for word in append_s(['a','b','c']): print word |
Ans: The above code adds a trailing s after each element of the list.
def append_s(words):
return [i+’s’ for i in words] ## another list comprehension
for word in append_s([‘a’,’b’,’c’]):
print word
Ans: best stored in a list of dictionaries..
dictionary format: {‘first_name’:’Ayush’,’last_name’:’Goel’}
Ans: Here are a few key points:
Why This Matters:
If you are applying for a Python position, you should know what it is and why it is so gosh-darn cool. And why it isn't o.O
def print_directory_contents(sPath):
"""
This function takes the name of a directory
and prints out the paths files within that
directory as well as any files contained in
contained directories.
This function is similar to os.walk. Please don't
use os.walk in your answer. We are interested in your
ability to work with nested structures.
"""
fill_this_in
Ans: def print_directory_contents(sPath):
import os
for sChild in os.listdir(sPath):
sChildPath = os.path.join(sPath,sChild)
if os.path.isdir(sChildPath):
print_directory_contents(sChildPath)
else:
print(sChildPath)
Pay Special Attention
Why This Matters:
Q133. Looking at the below code, write down the final values of A0, A1, ...An.
A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5)))
A1 = range(10)
A2 = sorted([i for i in A1 if i in A0])
A3 = sorted([A0[s] for s in A0])
A4 = [i for i in A1 if i in A3]
A5 = {i:i*i for i in A1}
A6 = [[i,i*i] for i in A1]
If you dont know what zip is don't stress out. No sane employer will expect you to memorize the standard library. Here is the output of help(zip).
zip(...)
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
Return a list of tuples, where each tuple contains the i-th element
from each of the argument sequences. The returned list is truncated
in length to the length of the shortest argument sequence.
If that doesn't make sense then take a few minutes to figure it out however you choose to.
Ans: A0 = {'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4} # the order may vary
A1 = range(0, 10) # or [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] in python 2
A2 = []
A3 = [1, 2, 3, 4, 5]
A4 = [1, 2, 3, 4, 5]
A5 = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6 = [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
Why This Matters
Ans: Python doesn't allow multi-threading in the truest sense of the word. It has a multi-threading package but if you want to multi-thread to speed your code up, then it's usually not a good idea to use it. Python has a construct called the Global Interpreter Lock (GIL). The GIL makes sure that only one of your 'threads' can execute at any one time. A thread acquires the GIL, does a little work, then passes the GIL onto the next thread. This happens very quickly so to the human eye it may seem like your threads are executing in parallel, but they are really just taking turns using the same CPU core. All this GIL passing adds overhead to execution. This means that if you want to make your code run faster then using the threading package often isn't a good idea.
There are reasons to use Python's threading package. If you want to run some things simultaneously, and efficiency is not a concern, then it's totally fine and convenient. Or if you are running code that needs to wait for something (like some IO) then it could make a lot of sense. But the threading library won't let you use extra CPU cores.
Multi-threading can be outsourced to the operating system (by doing multi-processing), some external application that calls your Python code (eg, Spark or Hadoop), or some code that your Python code calls (eg: you could have your Python code call a C function that does the expensive multi-threaded stuff).
Why This Matters
Because the GIL is an A-hole. Lots of people spend a lot of time trying to find bottlenecks in their fancy Python multi-threaded code before they learn what the GIL is.
Ans: Version control! At this point, you should act excited and tell them how you even use Git (or whatever is your favorite) to keep track of correspondence with Granny. Git is my preferred version control system, but there are others, for example subversion.
Why This Matters:
Because code without version control is like coffee without a cup. Sometimes we need to write once-off throw away scripts and that's ok, but if you are dealing with any significant amount of code, a version control system will be a benefit. Version Control helps with keeping track of who made what change to the code base; finding out when bugs were introduced to the code; keeping track of versions and releases of your software; distributing the source code amongst team members; deployment and certain automations. It allows you to roll your code back to before you broke it which is great on its own. Lots of stuff. It's just great.
def f(x,l=[]):
for i in range(x):
l.append(i*i)
print(l)
f(2)
f(3,[3,2,1])
f(3)
Ans:
[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]
Hu?
The first function call should be fairly obvious, the loop appends 0 and then 1 to the empty list, l. l is a name for a variable that points to a list stored in memory.
The second call starts off by creating a new list in a new block of memory. l then refers to this new list. It then appends 0, 1 and 4 to this new list. So that's great.
The third function call is the weird one. It uses the original list stored in the original memory block. That is why it starts off with 0 and 1.
Try this out if you don't understand:
l_mem = []
l = l_mem # the first call
for i in range(2):
l.append(i*i)
print(l) # [0, 1]
l = [3,2,1] # the second call
for i in range(3):
l.append(i*i)
print(l) # [3, 2, 1, 0, 1, 4]
l = l_mem # the third call
for i in range(3):
l.append(i*i)
print(l) # [0, 1, 0, 1, 4]
Ans: Monkey patching is changing the behaviour of a function or object after it has already been defined. For example:
import datetime
datetime.datetime.now = lambda: datetime.datetime(2012, 12, 12)
Most of the time it's a pretty terrible idea - it is usually best if things act in a well-defined way. One reason to monkey patch would be in testing. The mock package is very useful to this end.
Why This Matters
It shows that you understand a bit about methodologies in unit testing. Your mention of monkey avoidance will show that you aren't one of those coders who favor fancy code over maintainable code (they are out there, and they suck to work with). Remember the principle of KISS? And it shows that you know a little bit about how Python works on a lower level, how functions are actually stored and called and suchlike.
PS: it's really worth reading a little bit about mock if you haven't yet. It's pretty useful.
Ans: Use *args when we aren't sure how many arguments are going to be passed to a function, or if we want to pass a stored list or tuple of arguments to a function. **kwargsis used when we dont know how many keyword arguments will be passed to a function, or it can be used to pass the values of a dictionary as keyword arguments. The identifiers args and kwargs are a convention, you could also use *bob and **billy but that would not be wise.
Here is a little illustration:
def f(*args,**kwargs): print(args, kwargs)
l = [1,2,3]
t = (4,5,6)
d = {'a':7,'b':8,'c':9}
f()
f(1,2,3) # (1, 2, 3) {}
f(1,2,3,"groovy") # (1, 2, 3, 'groovy') {}
f(a=1,b=2,c=3) # () {'a': 1, 'c': 3, 'b': 2}
f(a=1,b=2,c=3,zzz="hi") # () {'a': 1, 'c': 3, 'b': 2, 'zzz': 'hi'}
f(1,2,3,a=1,b=2,c=3) # (1, 2, 3) {'a': 1, 'c': 3, 'b': 2}
f(*l,**d) # (1, 2, 3) {'a': 7, 'c': 9, 'b': 8}
f(*t,**d) # (4, 5, 6) {'a': 7, 'c': 9, 'b': 8}
f(1,2,*t) # (1, 2, 4, 5, 6) {}
f(q="winning",**d) # () {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
f(1,2,*t,q="winning",**d) # (1, 2, 4, 5, 6) {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
def f2(arg1,arg2,*args,**kwargs): print(arg1,arg2, args, kwargs)
f2(1,2,3) # 1 2 (3,) {}
f2(1,2,3,"groovy") # 1 2 (3, 'groovy') {}
f2(arg1=1,arg2=2,c=3) # 1 2 () {'c': 3}
f2(arg1=1,arg2=2,c=3,zzz="hi") # 1 2 () {'c': 3, 'zzz': 'hi'}
f2(1,2,3,a=1,b=2,c=3) # 1 2 (3,) {'a': 1, 'c': 3, 'b': 2}
f2(*l,**d) # 1 2 (3,) {'a': 7, 'c': 9, 'b': 8}
f2(*t,**d) # 4 5 (6,) {'a': 7, 'c': 9, 'b': 8}
f2(1,2,*t) # 1 2 (4, 5, 6) {}
f2(1,1,q="winning",**d) # 1 1 () {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
f2(1,2,*t,q="winning",**d) # 1 2 (4, 5, 6) {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
Why Care?
Sometimes we will need to pass an unknown number of arguments or keyword arguments into a function. Sometimes we will want to store arguments or keyword arguments for later use. Sometimes it's just a time saver.
Ans: Answer Background Knowledge:
These are decorators. A decorator is a special kind of function that either takes a function and returns a function, or takes a class and returns a class. The @ symbol is just syntactic sugar that allows you to decorate something in a way that's easy to read.
@my_decorator
def my_func(stuff):
do_things
Is equivalent to
def my_func(stuff):
do_things
my_func = my_decorator(my_func)
Click Here To learn More On Python
Actual Answer:
The decorators @classmethod, @staticmethod and @property are used on functions defined within classes. Here is how they behave:
class MyClass(object):
def __init__(self):
self._some_property = "properties are nice"
self._some_other_property = "VERY nice"
def normal_method(*args,**kwargs):
print("calling normal_method({0},{1})".format(args,kwargs))
@classmethod
def class_method(*args,**kwargs):
print("calling class_method({0},{1})".format(args,kwargs))
@staticmethod
def static_method(*args,**kwargs):
print("calling static_method({0},{1})".format(args,kwargs))
@property
def some_property(self,*args,**kwargs):
print("calling some_property getter({0},{1},{2})".format(self,args,kwargs))
return self._some_property
@some_property.setter
def some_property(self,*args,**kwargs):
print("calling some_property setter({0},{1},{2})".format(self,args,kwargs))
self._some_property = args[0]
@property
def some_other_property(self,*args,**kwargs):
print("calling some_other_property getter({0},{1},{2})".format(self,args,kwargs))
return self._some_other_property
o = MyClass()
# undecorated methods work like normal, they get the current instance (self) as the first argument
o.normal_method
# <bound method MyClass.normal_method of <__main__.MyClass instance at 0x7fdd2537ea28>>
o.normal_method()
# normal_method((<__main__.MyClass instance at 0x7fdd2537ea28>,),{})
o.normal_method(1,2,x=3,y=4)
# normal_method((<__main__.MyClass instance at 0x7fdd2537ea28>, 1, 2),{'y': 4, 'x': 3})
# class methods always get the class as the first argument
o.class_method
# <bound method classobj.class_method of <class __main__.MyClass at 0x7fdd2536a390>>
o.class_method()
# class_method((<class __main__.MyClass at 0x7fdd2536a390>,),{})
o.class_method(1,2,x=3,y=4)
# class_method((<class __main__.MyClass at 0x7fdd2536a390>, 1, 2),{'y': 4, 'x': 3})
# static methods have no arguments except the ones you pass in when you call them
o.static_method
# <function static_method at 0x7fdd25375848>
o.static_method()
# static_method((),{})
o.static_method(1,2,x=3,y=4)
# static_method((1, 2),{'y': 4, 'x': 3})
# properties are a way of implementing getters and setters. It's an error to explicitly call them
# "read only" attributes can be specified by creating a getter without a setter (as in some_other_property)
o.some_property
# calling some_property getter(<__main__.MyClass instance at 0x7fb2b70877e8>,(),{})
# 'properties are nice'
o.some_property()
# calling some_property getter(<__main__.MyClass instance at 0x7fb2b70877e8>,(),{})
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: 'str' object is not callable
o.some_other_property
# calling some_other_property getter(<__main__.MyClass instance at 0x7fb2b70877e8>,(),{})
# 'VERY nice'
# o.some_other_property()
# calling some_other_property getter(<__main__.MyClass instance at 0x7fb2b70877e8>,(),{})
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: 'str' object is not callable
o.some_property = "groovy"
# calling some_property setter(<__main__.MyClass object at 0x7fb2b7077890>,('groovy',),{})
o.some_property
# calling some_property getter(<__main__.MyClass object at 0x7fb2b7077890>,(),{})
# 'groovy'
o.some_other_property = "very groovy"
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: can't set attribute
o.some_other_property
# calling some_other_property getter(<__main__.MyClass object at 0x7fb2b7077890>,(),{})
# 'VERY nice'
class A(object):
def go(self):
print("go A go!")
def stop(self):
print("stop A stop!")
def pause(self):
raise Exception("Not Implemented")
class B(A):
def go(self):
super(B, self).go()
print("go B go!")
class C(A):
def go(self):
super(C, self).go()
print("go C go!")
def stop(self):
super(C, self).stop()
print("stop C stop!")
class D(B,C):
def go(self):
super(D, self).go()
print("go D go!")
def stop(self):
super(D, self).stop()
print("stop D stop!")
def pause(self):
print("wait D wait!")
class E(B,C): pass
a = A()
b = B()
c = C()
d = D()
e = E()
# specify output from here onwards
a.go()
b.go()
c.go()
d.go()
e.go()
a.stop()
b.stop()
c.stop()
d.stop()
e.stop()
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()
Ans:
The output is specified in the comments in the segment below:
a.go()
# go A go!
b.go()
# go A go!
# go B go!
c.go()
# go A go!
# go C go!
d.go()
# go A go!
# go C go!
# go B go!
# go D go!
e.go()
# go A go!
# go C go!
# go B go!
a.stop()
# stop A stop!
b.stop()
# stop A stop!
c.stop()
# stop A stop!
# stop C stop!
d.stop()
# stop A stop!
# stop C stop!
# stop D stop!
e.stop()
# stop A stop!
a.pause()
# ... Exception: Not Implemented
b.pause()
# ... Exception: Not Implemented
c.pause()
# ... Exception: Not Implemented
d.pause()
# wait D wait!
e.pause()
# ...Exception: Not Implemented
Why do we care?
Because OO programming is really, really important. Really. Answering this question shows your understanding of inheritance and the use of Python's super function. Most of the time the order of resolution doesn't matter. Sometimes it does, it depends on your application.Q141).
Consider the following code, what will it output?
class Node(object):
def __init__(self,sName):
self._lChildren = []
self.sName = sName
def __repr__(self):
return "<Node '{}'>".format(self.sName)
def append(self,*args,**kwargs):
self._lChildren.append(*args,**kwargs)
def print_all_1(self):
print(self)
for oChild in self._lChildren:
oChild.print_all_1()
def print_all_2(self):
def gen(o):
lAll = [o,]
while lAll:
oNext = lAll.pop(0)
lAll.extend(oNext._lChildren)
yield oNext
for oNode in gen(self):
print(oNode)
oRoot = Node("root")
oChild1 = Node("child1")
oChild2 = Node("child2")
oChild3 = Node("child3")
oChild4 = Node("child4")
oChild5 = Node("child5")
oChild6 = Node("child6")
oChild7 = Node("child7")
oChild8 = Node("child8")
oChild9 = Node("child9")
oChild10 = Node("child10")
oRoot.append(oChild1)
oRoot.append(oChild2)
oRoot.append(oChild3)
oChild1.append(oChild4)
oChild1.append(oChild5)
oChild2.append(oChild6)
oChild4.append(oChild7)
oChild3.append(oChild8)
oChild3.append(oChild9)
oChild6.append(oChild10)
# specify output from here onwards
oRoot.print_all_1()
oRoot.print_all_2()
Ans:
oRoot.print_all_1() prints:
<Node 'root'>
<Node 'child1'>
<Node 'child4'>
<Node 'child7'>
<Node 'child5'>
<Node 'child2'>
<Node 'child6'>
<Node 'child10'>
<Node 'child3'>
<Node 'child8'>
<Node 'child9'>
oRoot.print_all_2() prints:
<Node 'root'>
<Node 'child1'>
<Node 'child2'>
<Node 'child3'>
<Node 'child4'>
<Node 'child5'>
<Node 'child6'>
<Node 'child8'>
<Node 'child9'>
<Node 'child7'>
<Node 'child10'>
Why do we care?
Because composition and object construction is what objects are all about. Objects are composed of stuff and they need to be initialised somehow. This also ties up some stuff about recursion and use of generators.
Generators are great. You could have achieved similar functionality to print_all_2 by just constructing a big long list and then printing it's contents. One of the nice things about generators is that they don't need to take up much space in memory.
It is also worth pointing out that print_all_1 traverses the tree in a depth-first manner, while print_all_2 is width-first. Make sure you understand those terms. Sometimes one kind of traversal is more appropriate than the other. But that depends very much on your application.
Ans: A lot can be said here. There are a few main points that you should mention:
This explanation is CPython specific.
Place the following functions below in order of their efficiency. They all take in a list of numbers between 0 and 1. The list can be quite long. An example input list would be [random.random() for i in range(100000)]. How would you prove that your answer is correct?
def f1(lIn):
l1 = sorted(lIn)
l2 = [i for i in l1 if i<0.5]
return [i*i for i in l2]
def f2(lIn):
l1 = [i for i in lIn if i<0.5]
l2 = sorted(l1)
return [i*i for i in l2]
def f3(lIn):
l1 = [i*i for i in lIn]
l2 = sorted(l1)
return [i for i in l1 if i<(0.5*0.5)]
Ans:
Most to least efficient: f2, f1, f3. To prove that this is the case, you would want to profile your code. Python has a lovely profiling package that should do the trick.
import cProfile
lIn = [random.random() for i in range(100000)]
cProfile.run('f1(lIn)')
cProfile.run('f2(lIn)')
cProfile.run('f3(lIn)')
For completion's sake, here is what the above profile outputs:
>>> cProfile.run('f1(lIn)')
4 function calls in 0.045 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.009 0.009 0.044 0.044 <stdin>:1(f1)
1 0.001 0.001 0.045 0.045 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.035 0.035 0.035 0.035 {sorted}
>>> cProfile.run('f2(lIn)')
4 function calls in 0.024 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.008 0.008 0.023 0.023 <stdin>:1(f2)
1 0.001 0.001 0.024 0.024 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.016 0.016 0.016 0.016 {sorted}
>>> cProfile.run('f3(lIn)')
4 function calls in 0.055 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.016 0.016 0.054 0.054 <stdin>:1(f3)
1 0.001 0.001 0.055 0.055 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.038 0.038 0.038 0.038 {sorted}
Why Care?
Locating and avoiding bottlenecks is often pretty worthwhile. A lot of coding for efficiency comes down to common sense - in the example above it's obviously quicker to sort a list if it's a smaller list, so if you have the choice of filtering before a sort it's often a good idea. The less obvious stuff can still be located through use of the proper tools. It's good to know about these tools.
Ans: PYTHONPATH - It has a role similar to PATH. This variable tells the Python interpreter where to locate the module files imported into a program. It should include the Python source library directory and the directories containing Python source code. PYTHONPATH is sometimes preset by the Python installer.
Ans: PYTHONSTARTUP - It contains the path of an initialization file containing Python source code. It is executed every time you start the interpreter. It is named as .pythonrc.py in Unix and it contains commands that load utilities or modify PYTHONPATH.
Ans: PYTHONCASEOK − It is used in Windows to instruct Python to find the first case-insensitive match in an import statement. Set this variable to any value to activate it.
Ans: PYTHONHOME − It is an alternative module search path. It is usually embedded in the PYTHONSTARTUP or PYTHONPATH directories to make switching module libraries easy.
Ans: Python is a general-purpose programming language typically used for web development. ... SQLite is one free lightweight database commonly used by Python programmers to store data. Many highly trafficked websites, such as YouTube, are created using Python.
Ans: An interpreter is a program that reads and executes code. This includes source code, pre-compiled code, and scripts. Common interpreters include Perl, Python, and Ruby interpreters, which execute Perl, Python, and Ruby code respectively.
Ans: When he began implementing Python, Guido van Rossum was also reading the published scripts from “Monty Python's Flying Circus”, a BBC comedy series from the 1970s. Van Rossum thought he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python.
You may also interested in...