What is the output of the following code? Please explain.

Copy the code
  1. def extendList(val, list=[]): 
  2.     list.append(val) 
  3.     return list 
  4.  
  5. list1 = extendList(10) 
  6. list2 = extendList(123,[]) 
  7. list3 = extendList(‘a’) 
  8.  
  9. print “list1 = %s” % list1 
  10. print “list2 = %s” % list2 
  11. print “list3 = %s” % list3 

How can extendList’s definition be modified to produce the following expected behavior?

The output from the above code would be:

Copy the code
  1. list1 = [10, ‘a’] 
  2. list2 = [123] 
  3. list3 = [10, ‘a’] 

Many people misunderstand list1=[10] and list3=[‘ a ‘] because they assume that the default value of the list parameter will be set to [] every time extendList is called. But in reality, the new default list is created only once, at the moment the function is defined.

When extendList is called by a list without specifying a specific parameter, the values of this list are then used. This is because expressions with default arguments are evaluated when the function is defined, not when it is called. So list1 and List3 operate (evaluate) on the same default list. List2, on the other hand, operates (evaluates) on a separate list. (By passing an empty list of its own as the value of the list argument).

The definition of extendList can be modified as follows.

Although, to create a new list, there are no specific list parameters.

The following code might produce the desired result.

Copy the code
  1. def extendList(val, list=None): 
  2.   if list is None: 
  3.     list = [] 
  4.   list.append(val) 
  5.   return list 

With the above modifications, the output would be:

Copy the code
  1. list1 = [10] 
  2. list2 = [123] 
  3. list3 = [‘a’] 

2. What is the output of the following code? Please explain.

Copy the code
  1. def multipliers(): 
  2.   return [lambda x : i * x for i in range(4)] 
  3.  
  4. print [m(2) for m in multipliers()] 

How can you modify the multipliers definition above to produce the desired result?

The output from the code above is [6, 6, 6, 6] (not [0, 2, 4, 6]).

The problem is caused by delayed binding of Python closures. This means that when an inner function is called, the value of the parameter is looked up inside the closure. Therefore, when any function returned by multipliers() is called, the value of I will be looked up in a nearby range. At that point, whether or not the returned function is called, the for loop is complete and I is given the final value of 3.

Therefore, each time the returned function is multiplied by the passed value of 3, since the previous code passed the value of 2, they all end up returning 6(3*2). As it happens, The Hitchhiker’s Guide to Python also points out that there is another widely misunderstood point about lambdas, but not in this case. There is nothing special about a function created by lambda expressions; it is the same function created by DEF.

Here are some ways to solve this problem.

One solution is to use Python generators.

Copy the code
  1. def multipliers(): 
  2.   for i in range(4): yield lambda x : i * x 

Another solution is to create a closure that uses default functions to bind immediately.

Copy the code
  1. def multipliers(): 
  2.   return [lambda x, i=i : i * x for i in range(4)] 

An alternative is to use partial functions:

Copy the code
  1. from functools import partial 
  2. from operator import mul 
  3.  
  4. def multipliers(): 
  5.   return [partial(mul, i) for i in range(4)] 

3. What is the output of this code? Please explain.

Copy the code
  1. class Parent(object): 
  2.     x = 1 
  3.  
  4. class Child1(Parent): 
  5.     pass 
  6.  
  7. class Child2(Parent): 
  8.     pass 
  9.  
  10. print Parent.x, Child1.x, Child2.x 
  11. Child1.x = 2 
  12. print Parent.x, Child1.x, Child2.x 
  13. Parent.x = 3 
  14. print Parent.x, Child1.x, Child2.x 

The output will be:

Copy the code
  1. 1 1 1 
  2. 1 2 1 
  3. 2, 3, 3

What’s confusing or surprising to a lot of people is why the last line of output is 3, 2, 3 instead of 3, 2, 1. Why change the value of child2.x when changing parent. X? But at the same time does not change the value of child1.x?

The key to this answer is that in Python, class variables are passed internally as dictionaries.

If a variable name is not found in the dictionary under the current class. Search in a higher-level class (such as its parent) until the referenced variable name is found. (An attribute error will be raised if the reference variable name is not found in its own class or in a higher class.)

Therefore, set x = 1 in the parent class so that the variable x class (with the value 1) can be referenced in its class and its subclasses. That’s why the first print statement says 1, 1, 1, okay

Therefore, if any of its subclasses overwrite the value (for example, when we execute the statement child1.x = 2), the value is changed only in the subclass. That’s why the second print statement says 1, 2, 1, okay

Finally, if the value is modified in the Parent class (for example, when we execute the statement Parent. X = 3), the change will affect values that have not yet been overridden (Child2 in this case), which is why the third print statement outputs 3, 2, 3

What is the output of the following code under Python2? Please explain.

Copy the code
  1. def div1(x,y): 
  2.     print “%s/%s = %s” % (x, y, x/y) 
  3.  
  4. def div2(x,y): 
  5.     print “%s//%s = %s” % (x, y, x//y) 
  6.  
  7. Div1 (5, 2)
  8. div1(5.,2) 
  9. Div2 (5, 2)
  10. div2(5.,2.) 

How are the results different under Python3? (Assuming, of course, that the above print statement is translated into Python3 syntax)

In Python2, the above code output would be

Copy the code
  1. 5/2 = 2 
  2. 5.0/2 = 2.5 
  3. 5 / / 2 = 2
  4. / / 5.0 2.0 = 2.0

By default, Python 2 automatically performs an integer calculation if both are integers. So 5/2 is 2, and 5/2 is 2.5

Note that in Python2, you can override this behavior by adding the following reference.

Copy the code
  1. from future import division 

Also note that the // operator will always perform integer division, regardless of the operator type. This is why even in Python 2 5.0//2.0 results in 2.0. In Python3, however, there is no such feature,

For example, it does not perform integer division in cases where both ends are integers

So, in Python3, this would be the result:

Copy the code
  1. 5/2 = 2.5 
  2. 5.0/2 = 2.5 
  3. 5 / / 2 = 2
  4. / / 5.0 2.0 = 2.0

Note: In Python 3, the/operator does floating-point division, while // does full division (i.e., the quotient has no remainder; for example, 10 // 3 results in 3 and the remainder is cut off, whereas (-7) // 3 results in -3. This algorithm differs from many other programming languages in that their divisible operations are evaluated in the direction of 0. In Python 2, / is exactly divisible, the same as the // operator in Python 3.)

5. What will be the output of the following code?

Copy the code
  1. list = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] 
  2. print list[10:] 

The following code will print [] without raising an IndexError. As expected, try to get the members of a list with an index that exceeds the number of members.

For example, trying to get list[10] and subsequent members will result in IndexError.

However, trying to get a slice of the list and starting with an index that exceeds the number of members does not produce an IndexError, but simply returns an empty list.

This can be a particularly nasty puzzle, since there are no bugs at runtime, making bugs hard to track down.

6. Consider the following code snippet:

Copy the code
  1. list = [ [ ] ] * 5 
  2. list  # output? 
  3. list[0].append(10) 
  4. list  # output? 
  5. list[1].append(20) 
  6. list  # output? 
  7. list.append(30) 
  8. list  # output? 

What will be the output of lines 2,4,6,8? Try to explain.

The output is as follows:

Copy the code
  1. [], [], [], [], []
  2. [[10], [10], [10], [10]
  3. [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]] 
  4. [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30] 

The explanation is as follows:

The output of the first line is intuitively easy to understand, for example list = [[]] * 5 simply creates five empty lists. However, the key point to understand about the expression list=[[]] * 5 is that it does not create a list containing five separate lists, but rather that it creates a list containing five references to the same list. Only with this in mind can we better understand the following output.

List [0].append(10) appends 10 to the first list.

But since all five lists refer to the same list, the result will be:

Copy the code
  1. [[10], [10], [10], [10]

Similarly, list[1].append(20) appends 20 to the second list. But again, because all five lists refer to the same list, the output is now:

Copy the code
  1. [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]] 

By contrast, list.append(30) appends the entire new element to the outer list, so the result is:

Copy the code
  1. [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30] 

7, Given a list of N numbers.

Given a list of N numbers.

Use a single list generator to produce a new list that contains only values that satisfy the following criteria:

(a) I value

(b) Elements are even-numbered slices of the original list.

For example, if list[2] contains even values. This value should be included in the new list. Because this number is both on the even sequence of the original list (2 is even). However, if list[3] contains an even number,

That number should not be included in the new list because it is in the odd sequence of the original list.

The simple solution to this problem is as follows:

Copy the code
  1. [x for x in list[::2] if x%2 == 0] 

For example, given the following list:

Copy the code
  1. list = [ 1 , 3 , 5 , 8 , 10 , 13 , 18 , 36 , 78 ] 

X for x in list[::2] if x%2 == 0

Copy the code
  1. [10, 18, 78] 

The way this expression works is, the first step is to take the number of even slices,

The second step is to eliminate all odd numbers.

Given a subclass of the following dictionary, does the following code work? Why is that?

Copy the code
  1. class DefaultDict(dict): 
  2.   def __missing__(self, key): 
  3.     return []  
Copy the code
  1. d = DefaultDict() 
  2. d[‘florp’] = 127 

Able to run.

When a key is missing, DefaultDict is executed, and the dictionary instance automatically instantiates the sequence.


Developers

Source: 51 cto