Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Zusammenfassung der Python-Interviewfragen (mit Antworten)

Detaillierte Zusammenfassung der Python-Interviewfragen (mit Antworten)

不言
不言nach vorne
2019-02-23 13:15:367536Durchsuche

Detaillierte Zusammenfassung der Python-Interviewfragen (mit Antworten)

Dieser Artikel enthält eine Zusammenfassung der Python-Interviewfragen (mit Antworten). Ich hoffe, dass er für Sie nützlich ist. hat geholfen.

Empfohlene verwandte Artikel : „ Zusammenfassung der Python-Interviewfragen im Jahr 2020 (aktuell)

1 . Was ist die Ausgabe des folgenden Codes? Bitte erläutern Sie es.

def extendList(val, list=[]):
    list.append(val)
    return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

Wie ändere ich die Definition von „extendList“, um das folgende erwartete Verhalten zu erzeugen?

Das Ausgabeergebnis des obigen Codes lautet:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

Viele Leute werden das fälschlicherweise denken list1 = [10], list3 = ['a'], weil sie dachten, dass bei jedem Aufruf von extensionList der Standardwert des Listenparameters auf [] gesetzt wird. Die tatsächliche Situation ist jedoch, dass die neue Standardliste nur ist Wird zum Zeitpunkt der Definition der Funktion verwendet. Einmal erstellt.

Wenn „extendList“ ohne Angabe einer bestimmten Parameterliste aufgerufen wird, werden anschließend die Werte dieser Liste verwendet. Dies liegt daran, dass Ausdrücke mit Standardparametern ausgewertet werden, wenn die Funktion definiert wird, und nicht, wenn sie aufgerufen wird. Daher arbeiten (berechnen) list1 und list3 mit derselben Standardliste. Und list2 arbeitet (berechnet) auf einer separaten Liste. (Durch Übergabe einer eigenen leeren Liste als Wert des Listenarguments).

Die Definition von „extendList“ kann wie folgt geändert werden.

Erstellt jedoch eine neue Liste ohne spezifische Listenparameter.

Der folgende Code kann zu den gewünschten Ergebnissen führen.

def extendList(val, list=None):
  if list is None:
    list = []
  list.append(val)
  return list

Mit der obigen Änderung wird das Ausgabeergebnis zu:

list1 = [10]
list2 = [123]
list3 = ['a']

2. Was wird das Ausgabeergebnis des folgenden Codes sein? Bitte erläutern Sie es.

def multipliers():
  return [lambda x : i * x for i in range(4)]
print [m(2) for m in multipliers()]

Wie können Sie die Definition der Multiplikatoren oben ändern, um die gewünschten Ergebnisse zu erzielen?

Das Ausgabeergebnis des obigen Codes ist [6, 6, 6, 6] (nicht [0, 2, 4, 6], wie wir dachten).

Das obige Problem wird durch die verzögerte Bindung von Python-Abschlüssen verursacht. Das bedeutet, dass beim Aufruf der inneren Funktion der Wert des Arguments innerhalb des Abschlusses nachgeschlagen wird. Wenn daher eine von multipliers() zurückgegebene Funktion aufgerufen wird, wird der Wert von i im nahegelegenen Bereich nachgeschlagen. Zu diesem Zeitpunkt ist die for-Schleife abgeschlossen und i wird der Endwert 3 zugewiesen, unabhängig davon, ob die zurückgegebene Funktion aufgerufen wurde.

Daher wird jedes Mal, wenn die zurückgegebene Funktion mit dem übergebenen Wert 3 multipliziert wird, schließlich 6 (3*2) zurückgegeben, da der im vorherigen Code übergebene Wert 2 ist. Zufälligerweise wurde in „The Hitchhiker’s Guide to Python“ auch darauf hingewiesen, dass es auch einen weithin missverstandenen Wissenspunkt im Zusammenhang mit Lambdas-Funktionen gibt, der sich jedoch von diesem Fall unterscheidet. Die durch den Lambda-Ausdruck erstellte Funktion ist nichts Besonderes. Sie ist tatsächlich dieselbe wie die durch def erstellte Funktion.

Hier sind einige Möglichkeiten, dieses Problem zu lösen.

Eine Lösung ist die Verwendung von Python-Generatoren.

def multipliers():
  for i in range(4): yield lambda x : i * x

Eine andere Lösung besteht darin, einen Abschluss zu erstellen und ihn sofort mit der Standardfunktion zu binden.

def multipliers():
  return [lambda x, i=i : i * x for i in range(4)]

Eine Alternative ist die Verwendung einer Teilfunktion:

from functools import partial
from operator import mul
def multipliers():
  return [partial(mul, i) for i in range(4)]

3. Was wird die Ausgabe des folgenden Codes sein? Bitte erläutern Sie es.

class Parent(object):
    x = 1
class Child1(Parent):
    pass
class Child2(Parent):
    pass
print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x

Das Ausgabeergebnis wird sein:

1 1 1
1 2 1
3 2 3

Was viele Leute verwirrt oder überrascht, ist, warum die letzte Ausgabezeile 3 2 3 statt 3 2 1 ist. Warum auch, wenn parent.x geändert wird? Wert von child2.x geändert? Aber gleichzeitig wird der Wert von Child1.x nicht verändert?

Der Schlüssel zu dieser Antwort liegt darin, dass in Python Klassenvariablen intern als Wörterbuch übergeben werden.

Wenn im Wörterbuch unter der aktuellen Klasse kein Variablenname gefunden wird. Suchen Sie dann umfassend in übergeordneten Klassen (z. B. der übergeordneten Klasse), bis der referenzierte Variablenname gefunden wird. (Wenn der Referenzvariablenname nicht in der eigenen Klasse oder einer übergeordneten Klasse gefunden wird, wird ein Attributfehler ausgelöst.)

Setzen Sie daher in der übergeordneten Klasse x = 1 und lassen Sie die Variable x Klasse (mit Wert 1) Kann in seiner Klasse und seinen Unterklassen referenziert werden. Aus diesem Grund lautet die Ausgabe der ersten print-Anweisung 1 1 1

Wenn also eine ihrer Unterklassen mit einem Wert überschrieben wird (z. B. wenn wir die Anweisung Child1.x = 2 ausführen), ist dieser Wert Nur in Unterklassen geändert. Aus diesem Grund lautet die Ausgabe der zweiten print-Anweisung 1 2 1

Wenn dieser Wert schließlich in der übergeordneten Klasse geändert wird (z. B. wenn wir die Anweisung Parent.x = 3 ausführen), ändert sich diese Änderung Dies wirkt sich auf die Werte aus, die von der Unterklasse nicht überschrieben wurden (in diesem Beispiel Child2). Aus diesem Grund lautet das Ausgabeergebnis der dritten Druckanweisung 3 2 3

4 das Ergebnis unter Python2 Was wird es sein? Bitte erläutern Sie es.

def div1(x,y):
    print "%s/%s = %s" % (x, y, x/y)
def div2(x,y):
    print "%s//%s = %s" % (x, y, x//y)
div1(5,2)
div1(5.,2)
div2(5,2)
div2(5.,2.)

Wie werden sich die Ergebnisse unter Python3 unterscheiden? (Vorausgesetzt natürlich, dass die obige Druckanweisung in die Syntax von Python3 konvertiert wird)

In Python2 lautet die Ausgabe des obigen Codes

5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

Standardmäßig führt Python 2 automatisch ganzzahlige Berechnungen durch wenn beide eine ganze Zahl sind. Daher ergibt 5/2 2 und 5./2 ergibt 2,5

Beachten Sie, dass Sie dieses Verhalten in Python 2 überschreiben können, indem Sie die folgende Referenz hinzufügen.

aus zukünftiger Importdivision

Beachten Sie außerdem, dass der //-Operator immer eine ganzzahlige Division durchführt, unabhängig vom Typ des Operators. Deshalb ist selbst in Python 2 das Ergebnis von 5.0//2.0 2.0. In Python3 gibt es diese Funktion jedoch nicht,

例如,在两端都是整形的情况下,它不会执行整形除法

因此,在Python3中,将会是如下结果:

5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

注: 在 Python 3 中,/ 操作符是做浮点除法,而 // 是做整除(即商没有余数,比如 10 // 3 其结果就为 3,余数会被截除掉,而 (-7) // 3 的结果却是 -3。这个算法与其它很多编程语言不一样,需要注意,它们的整除运算会向0的方向取值。而在 Python 2 中,/ 就是整除,即和 Python 3 中的 // 操作符一样)

5、下面代码的输出结果将是什么?

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]

下面的代码将输出[],不会产生IndexError错误。就像所期望的那样,尝试用超出成员的个数的index来获取某个列表的成员。

例如,尝试获取list[10]和之后的成员,会导致IndexError.

然而,尝试获取列表的切片,开始的index超过了成员个数不会产生IndexError,而是仅仅返回一个空列表。

这成为特别让人恶心的疑难杂症,因为运行的时候没有错误产生,导致bug很难被追踪到。

6、考虑下列代码片段:

list = [ [ ] ] * 5
list  # output?
list[0].append(10)
list  # output?
list[1].append(20)
list  # output?
list.append(30)
list  # output?

2,4,6,8行将输出什么结果?试解释。

输出的结果如下:

[[], [], [], [], []]
[[10], [10], [10], [10], [10]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]

解释如下:

第一行的输出结果直觉上很容易理解,例如 list = [ [ ] ] * 5 就是简单的创造了5个空列表。然而,理解表达式list=[ [ ] ] * 5的关键一点是它不是创造一个包含五个独立列表的列表,而是它是一个创建了包含对同一个列表五次引用的列表。只有了解了这一点,我们才能更好的理解接下来的输出结果。

list[0].append(10) 将10附加在第一个列表上。

但由于所有5个列表是引用的同一个列表,所以这个结果将是:

[[10], [10], [10], [10], [10]]

同理,list[1].append(20)将20附加在第二个列表上。但同样由于5个列表是引用的同一个列表,所以输出结果现在是:

[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]

作为对比, list.append(30)是将整个新的元素附加在外列表上,因此产生的结果是: [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30].

7、Given a list of N numbers。

给定一个含有N个数字的列表。

使用单一的列表生成式来产生一个新的列表,该列表只包含满足以下条件的值:

(a)偶数值

(b)元素为原始列表中偶数切片。

例如,如果list[2]包含的值是偶数。那么这个值应该被包含在新的列表当中。因为这个数字同时在原始列表的偶数序列(2为偶数)上。然而,如果list[3]包含一个偶数,

那个数字不应该被包含在新的列表当中,因为它在原始列表的奇数序列上。

对此问题的简单解决方法如下:

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

例如,给定列表如下:

list = [ 1 , 3 , 5 , 8 , 10 , 13 , 18 , 36 , 78 ]

列表生成式[x for x in list[::2] if x%2 == 0] 的结果是,

[10, 18, 78]

这个表达式工作的步骤是,第一步取出偶数切片的数字,

第二步剔除其中所有奇数。

8、给定以下字典的子类,下面的代码能够运行么?为什么?

class DefaultDict(dict):
  def __missing__(self, key):
    return []d = DefaultDict()
d['florp'] = 127

能够运行。

当key缺失时,执行DefaultDict类,字典的实例将自动实例化这个数列。

相关学习推荐:python视频教程

Das obige ist der detaillierte Inhalt vonDetaillierte Zusammenfassung der Python-Interviewfragen (mit Antworten). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:公众号:马哥Linux运维. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen