Python の面接でテストする必要があるコードの質問

不言
リリース: 2020-09-03 15:33:38
転載
4589 人が閲覧しました

Python の面接でテストする必要があるコードの質問

この記事の内容は、Python の面接でテストする必要があるコードの質問に関するものです。一定の参考価値があります。困っている友人は参照してください。お役に立てば幸いです。あなたに、助けられました。

おすすめ関連記事:「2020年Python面接質問まとめ(最新)

# #質問 1: 次のコードの出力は何になりますか? 答えて説明してください。

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
ログイン後にコピー

答えは

1 1 1
1 2 1
3 2 3
ログイン後にコピー

です。混乱したり驚いたりするかもしれませんが、最後の行の出力が 3 2 1 ではなく 3 2 3 であることです。 Parent.x の値を変更すると Child2.x の値も変更されるのに、同時に Child1.x の値は変更されないのはなぜですか?

この答えの鍵は、Python ではクラス変数が内部的に辞書として扱われるということです。現在のクラスの辞書に変数名が見つからない場合は、参照される変数名が見つかるまで祖先クラス (親クラスなど) が検索されます (参照される変数名がそれ自体のクラスにも存在しない場合)。祖先クラス) クラスでは、AttributeError 例外が発生します)。

したがって、親クラスで x = 1 を設定すると、そのクラスおよびそのサブクラスへの参照でクラス変数 X の値が 1 になります。これは、最初の print ステートメントの出力が 1 1 1 であるためです。

その後、そのサブクラスのいずれかが値をオーバーライドした場合 (たとえば、ステートメント Child1.x = 2 を実行した場合)、値はサブクラス内でのみ変更されます。そのため、2 番目の print ステートメントの出力は 1 2 1 になります。

最後に、親クラスで値が変更された場合 (たとえば、ステートメント Parent.x = 3 を実行した場合)、この変更は、値をオーバーライドしないサブクラスの値に影響します (この例では、この例で影響を受けるサブクラスは Child2) です。そのため、3 番目の印刷出力は 3 2 3 になります。

質問 2: 次のコードの出力は何になりますか? 答えと説明を教えてください。

def p1(x,y):
    print("%s/%s = %s" % (x, y, x/y))

def p2(x,y):
    print("%s//%s = %s" % (x, y, x//y))

p1(5,2)
p1(5.,2)
p2(5,2)
p2(5.,2.)
ログイン後にコピー
5/2 = 2
5.0/2.0=2.5
5/2=2
5/2=2
ログイン後にコピー

回答

この回答は、実際には、Python 2 を使用しているか Python 3 を使用しているかによって異なります。

Python 3 では、必要な出力は次のとおりです。

5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
ログイン後にコピー

ただし、Python 2 では、上記のコードの出力は次のようになります。

5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
ログイン後にコピー

Default (オペランドが 2 つの場合)はすべて整数であり、Python 2 は自動的に整数の計算を実行します。結果として、5/2 の値は 2 になりますが、5./2 の値は "2.5`` になります。

ただし、Python 2 ではこの動作をオーバーライドできることに注意してください (たとえば、 Python 3 で必要なことは、次の import を追加することで実現できます:

from__future__ import pision

また、「二重ダッシュ」(//) 演算子は、オペランドに関係なく、常に整数の除算を実行することにも注意してください。

注: Python 3 では、/ 演算子は浮動小数点の除算を実行し、// は整数の除算を実行します (つまり、商には余りがありません)。 , 例: 10 / / 3 結果は 3 で、余りは切り捨てられ、(-7) // 3 の結果は -3 です。このアルゴリズムは他の多くのプログラミング言語とは異なります。整数であることに注意してください。除算演算は 0 に向かって移動します。値の方向です。Python 2 では、/ は整数の除算であり、Python 3 の // 演算子と同じです。)

質問 3:次のコードが出力されますか?

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]
ログイン後にコピー

Answer上記のコードは [ ] を出力し、IndexError を引き起こしません。

ご想像のとおり、リストのインデックス メンバーを超える値にアクセスしようとすると、IndexError が発生します (例: 上記のリストの list[10] にアクセスする)。ただし、インデックス内のメンバーの数を超えるインデックスで始まるリストのスライスにアクセスしようとすると、IndexError が発生します。 list は IndexError を引き起こさず、単に空のリストを返します。

厄介な小さな問題は、これがバグを引き起こすことと、実行時にエラーが発生しないため、問題の追跡が難しいことです。

質問 4: 次のコードの出力は何になりますか? 答えを述べて説明してください?

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

print [m(2) for m in multipliers()]
ログイン後にコピー

望ましい結果を生み出すために乗算器の定義をどのように変更しますか?

回答

上記のコードの出力は、([0, 2, 4, 6] ではなく) [6, 6, 6, 6] です。

この理由は、Python のクロージャの遅延バインディングが遅延バインディングを引き起こすためであり、これは、内部関数が呼び出されたときにクロージャ内の変数が検索されることを意味します。 () が呼び出されたとき、その中に i の値が入っている 呼び出されたときに周囲のスコープで検索される その時点で、どの戻り関数が呼び出されても for ループは完了しており、最終的な の値はi は 3 です。したがって、返される各関数乗算の値は 3 です。したがって、2 に等しい値が上記のコードに渡されると、値 6 (例: 3 x 2) が返されます。

(顺便说下,正如在 The Hitchhiker’s Guide to Python 中指出的,这里有一点普遍的误解,是关于 lambda 表达式的一些东西。一个 lambda 表达式创建的函数不是特殊的,和使用一个普通的 def 创建的函数展示的表现是一样的。)

这里有两种方法解决这个问题

最普遍的解决方案是创建一个闭包,通过使用默认参数立即绑定它的参数。例如:

def multipliers():
    return [lambda x, i=i : i * x for i in range(4)]
ログイン後にコピー

另外一个选择是,你可以使用 functools.partial 函数

from functools import partial
from operator import mul

def multipliers():
    return [partial(mul, i) for i in range(4)]
ログイン後にコピー

问题五:以下的代码的输出将是什么? 说出你的答案并解释?

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
ログイン後にコピー

你将如何修改 extendList 的定义来产生期望的结果

以上代码的输出为:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
ログイン後にコピー

许多人会错误的认为 list1 应该等于 [10] 以及 list3 应该等于 [‘a’]。认为 list 的参数会在 extendList 每次被调用的时候会被设置成它的默认值 [ ]。

尽管如此,实际发生的事情是,新的默认列表仅仅只在函数被定义时创建一次。随后当 extendList 没有被指定的列表参数调用的时候,其使用的是同一个列表。这就是为什么当函数被定义的时候,表达式是用默认参数被计算,而不是它被调用的时候。

因此,list1 和 list3 是操作的相同的列表。而 "`list2是操作的它创建的独立的列表(通过传递它自己的空列表作为list"参数的值)。

extendList 函数的定义可以做如下修改,但,当没有新的 list 参数被指定的时候,会总是开始一个新列表,这更加可能是一直期望的行为。

def extendList(val, list=None):
    if list is None:
        list = []
    list.append(val)
    return list
ログイン後にコピー

使用这个改进的实现,输出将是:

list1 = [10]
list2 = [123]
list3 = ['a']
ログイン後にコピー

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

以上がPython の面接でテストする必要があるコードの質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!