21

私は時々Pythonを使用していて、コーディングの「Pythonic」な方法を発見しています。コードで多くのタプルを使用していますが、それらのほとんどは極座標またはデカルト座標です。

私はこれを書いていることに気づきました:

window.set_pos([18,8])

これの代わりに :

window.set_pos((18,8))

二重括弧を取り除くために、私は読みにくいと感じました。

私のコードは正しく機能しているので、Pythonはリストからタプルへの型変換を自動的に行っているようです。

しかし、それはコーディングするのに良い方法ですか?読みやすいコードを書くために使用できるプレゼンテーションのヒントはありますか?

確かに啓発的な答えをよろしくお願いします。

4

6 に答える 6

25

どこにでもあるリストを優先して、タプルを避けることを慎重に決定したいと思います。disモジュールを使用したことがありますか?タプルを作成するリストとタプルを作成するときに、Pythonがバイトコードレベルで何をしているのかを見てください。

>>> def f():
...     x = [1,2,3,4,5,6,7]
...     return x
... 
>>> def g():
...     x = (1,2,3,4,5,6,7)
...     return x
... 
>>> import dis
>>> dis.dis(f)
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               2 (2)
              6 LOAD_CONST               3 (3)
              9 LOAD_CONST               4 (4)
             12 LOAD_CONST               5 (5)
             15 LOAD_CONST               6 (6)
             18 LOAD_CONST               7 (7)
             21 BUILD_LIST               7
             24 STORE_FAST               0 (x)

  3          27 LOAD_FAST                0 (x)
             30 RETURN_VALUE     
>>>
>>>   
>>> dis.dis(g)
  2           0 LOAD_CONST               8 ((1, 2, 3, 4, 5, 6, 7))
              3 STORE_FAST               0 (x)

  3           6 LOAD_FAST                0 (x)
              9 RETURN_VALUE   

GUIアプリケーションではおそらく問題になることはありませんが(例のように)、パフォーマンス上の理由から、コード内のあらゆる場所で問題が発生する場合は注意が必要です。

于 2012-06-29T12:46:49.580 に答える
12

あなたは言う

Pythonはリストからタプルへの型変換を自動的に行っているようです

それは疑わしいです。リストとタプルはどちらもシーケンスタイプであるため、どちらも同じ動作の多くを実装します。使用しているGUIライブラリは、リストのみの動作を必要としないようにする必要があります。

多くの場合、これを行うのはおそらく問題ありませんが、リストはタプルよりも少し多くのスペースを占めることに注意してください。

>>> sys.getsizeof((1, 2))
72
>>> sys.getsizeof([1, 2])
88

また、いくつかの点でタプルよりも遅い場合があります。

>>> lst, tup = [1, 2], (1, 2)
>>> def unpack(x):
...     a, b = x
...     
>>> %timeit unpack(tup)
10000000 loops, best of 3: 163 ns per loop
>>> %timeit unpack(lst)
10000000 loops, best of 3: 172 ns per loop

これらは非常に小さな違いであり、数十億の呼び出しのように、はるかに大きなスケールに到達するまで問題にはならないため、トレードオフはそれだけの価値があります。

それでも、私は人々がこれを頻繁に行うのを見ません。読みやすさのトリックのように思えますが、状況によっては予期しない結果が生じる可能性があります。たとえば、後で再度使用する予定のリストを渡す場合は、関数内で変更しないように注意する必要があります。最後に、JFセバスティアンが正しく指摘しているように、タプルとリストはわずかに異なることを意味する傾向があります。型にはまらない方法でそれらを使用すると、求めている読みやすさの向上が無効になる可能性があります。

于 2012-06-29T12:27:05.210 に答える
8

タプルとリストがあなたのケースのパフォーマンスに顕著な違いをもたらすことを私は真剣に疑っています。プロファイラーからの指示がない限り、マイクロ最適化を行わないでください。読みやすさが優先されます。

listtupleは両方ともシーケンスタイプです。

意味的にはタプルが望ましい場合があります(タプルには構造があり、リストには順序がありますを参照)。位置は、x、y属性を持つ単一のオブジェクトです。

この場合、視覚的にリストが読みやすくなる可能性があります。

何を選択しても、一貫性があります。

window以下をサポートしているかどうかを確認してください。

window.pos = 18, 8

それを実装するための可能な方法はposプロパティset_pos()を作成し、セッターとしてバインドすること です。

于 2012-06-29T13:28:20.480 に答える
4

IMOを使用する唯一の利点は(18,8)[18,8]タプルオブジェクトが不変であり、渡される関数内で変更されないことを確認できる一方で、[18,8]簡単に変更できることです。

于 2012-06-29T12:24:40.420 に答える
4

set_posメソッドが明示的に行わない限り、Pythonはリストからタプルへの自動変換を行いません。タプルとリストのプロトコルは非常に似ているため、そのプロトコル内で互換性がある傾向があります。特にタプルはハッシュできる不変であり、リストはそうではないため、まだ問題が発生する可能性があります。

あなたの質問に答えるには、

window.set_pos( (18,18) )

適切なスペースは、コーディングスタイルで奇跡を起こします。

于 2012-06-29T12:26:03.230 に答える
0

パラメータがタプルであるという事実を強調したい場合は、明示的に変換できます。

window.set_pot(tuple([18, 18]))
于 2012-06-29T12:22:45.183 に答える