0

「コンピューター科学者のように考える方法: Python 2nd Edition で学習する」ドキュメントを読んでいます。第 9 章の最後に演習 11 があり、doctest に合格するための Python コードを書くよう求められます。

私の最初の解決策:

def add_column(matrix):
"""
  >>> m = [[0, 0], [0, 0]]
  >>> add_column(m)
  [[0, 0, 0], [0, 0, 0]]
  >>> n = [[3, 2], [5, 1], [4, 7]]
  >>> add_column(n)
  [[3, 2, 0], [5, 1, 0], [4, 7, 0]]
  >>> n
  [[3, 2], [5, 1], [4, 7]]
"""
result = matrix[:]
for index in range(len(matrix)):
    result[index] += [0]
return result


if __name__ == "__main__":
    import doctest
    doctest.testmod()

ただし、このコードは 2 番目のテストに合格しませんでした。forループの本体を次のように変更しました。

result[index] = result[index] + [0]

コードはすべてのテストに合格します。しかし、このコードの変更がどのように問題を解決したのか理解できません。result[index] = result[index] + [0]の明示的な形式だと思ったresult[0] += [0]のに、なぜ動作が異なるのですか?

私の答えをソリューションで提供されているコードと比較したところ、問題はリストのクローンを作成した方法にあると思われます。ソリューションでは、次のように行われます: result = [d[:] for d in matrix]、この場合、最初のforループが機能します。しかし、なぜ機能しresult = matrix[:]ないのですか?新しいオブジェクトではなく、エイリアスを作成していますか?

また、誰かがどのよう[d[:] for d in matrix]に解析され、そのような構文がいつ使用されるかを説明できますか? forループをこのように使用する方法は見たことがなく、レッスンでも説明/実演されていません。

4

1 に答える 1

0

次の理由により、リストは複製されていません。

result = matrix[:]

実際にリストをコピーします。ただし、リストアイテムをコピーしていません。Pythonは参照によってリスト項目を処理するためresult[0]matrix[0]考えられていても同じリストオブジェクトを指し、result異なるmatrixリストを指します。

[d[:] for d in matrix]メインリストとリスト要素の両方をmatrix複製します。これは、新しいリストで(その要素への参照を使用するのではなく)各要素のコピーを繰り返して作成するためです。

このモジュールを使用することもできcopyます。これは、dictも処理するため特に便利です。またcopy.deepcopy、深さが不明な多次元リストのクローンを作成できます:http: //docspy2zh.readthedocs.org/en/latest/library/copy。 html(ただし、ここで学習しようとしていることの範囲外であれば十分に公平です)。

'+='と'=... + ...'の違いについても、少し驚いたことを告白します。このような状況では、私はを使用する傾向がありresult[index].append(0)ます。これにより、そのあいまいさを回避できます。もちろん、それは答えではありません。

于 2012-08-12T11:26:50.857 に答える