元组可读性:[0,0] vs(0,0)

时间:2012-06-29 12:19:21

标签: python tuples readability

我有几次使用Python,我发现了“pythonic”编码方式。 我在代码中使用了很多元组,其中大多数都是极坐标或笛卡尔坐标。

我发现自己在写这个:

window.set_pos([18,8])

而不是:

window.set_pos((18,8))

摆脱我发现难以阅读的双重括号。

似乎python自动进行从列表到元组的类型转换,因为我的代码正常工作。

但它是一种很好的编码方式吗? 您是否有任何可用于编写可读代码的演示提示?

提前感谢您的答案。

6 个答案:

答案 0 :(得分: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应用程序中的问题(正如您的示例所示),但出于性能原因,您可能需要小心在代码中的任何位置执行此操作。

答案 1 :(得分:12)

你说

  

似乎python自动进行从列表到元组的类型转换

这是值得怀疑的。由于列表和元组都是sequence types,因此它们都实现了许多相同的行为,并且您使用的任何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

这些非常小差异在你达到更大规模之前无关紧要 - 比如数十亿次电话 - 所以权衡可能是值得的它

但是,我并不认为人们经常这样做。这似乎是一个很好的可读性技巧,但在某些情况下可能会产生意想不到的后果。例如,如果您稍后要再次使用列表,那么您必须注意不要在函数内部修改它。最后,正如J.F. Sebastian正确指出的那样,元组和列表倾向于意味着稍微不同的东西;以非常规方式使用它们可能会否定您寻求的可读性提升。

答案 2 :(得分:8)

我严重怀疑元组与列表在你的情况下在性能上有显着差异。除非您的分析师这样说,否则不要进行微观优化。可读性是一个优先事项。

listtuple都是sequence types

语义元组可能更受欢迎(参见Tuples have structure, lists have order)。位置是具有x,y属性的单个对象。

在这种情况下,

视觉列表可能更容易阅读。

无论你选择什么,只要保持一致

检查window是否支持以下内容:

window.pos = 18, 8

实现它的一种可能方法是将pos设为property并将set_pos()绑定为设置者。

答案 3 :(得分:4)

IMO使用(18,8)而不是[18,8]的唯一好处是元组对象是不可变的,你可以确定它不会在它传递的函数内被更改,而{{1可以很容易地改变。

答案 4 :(得分:4)

Python没有进行从列表到元组的任何自动转换,除非set_pos方法明确地这样做。元组和列表具有非常相似的协议,因此它们在该协议中往往是可互换的。你可能仍然会破坏一些东西,特别是因为元组是一个可以被散列的不可变元素,而一个列表则不是。

要回答您的问题,请写下

window.set_pos( (18,18) )

适当的空间可以创造出具有编码风格的奇迹。

答案 5 :(得分:0)

如果你想强调你的参数是一个元组的事实,你可以明确地转换它:

window.set_pot(tuple([18, 18]))