为什么是Python’;s函数调用语义传入关键字参数是否未排序?
使用函数定义中的双星语法,我们得到了一个规则字典。问题是它会使用户输入顺序松动。有时,我们可能想知道关键字参数传递到函数的顺序 由于通常一个函数调用不涉及很多参数,我不认为这是一个性能问题,所以我想知道为什么默认情况下不维护顺序 我知道我们可以使用:为什么是Python’;s函数调用语义传入关键字参数是否未排序?,python,Python,使用函数定义中的双星语法,我们得到了一个规则字典。问题是它会使用户输入顺序松动。有时,我们可能想知道关键字参数传递到函数的顺序 由于通常一个函数调用不涉及很多参数,我不认为这是一个性能问题,所以我想知道为什么默认情况下不维护顺序 我知道我们可以使用: from collections import Ordereddict def my_func(kwargs): print kwargs my_func(Ordereddict(a=1, b=42)) 但它不如: def my_func
from collections import Ordereddict
def my_func(kwargs):
print kwargs
my_func(Ordereddict(a=1, b=42))
但它不如:
def my_func(**kwargs):
print kwargs
my_func(a=1, b=42)
[编辑1]:
1) 我认为有两种情况:
- 我需要知道顺序,用户通过文档了解这种行为
- 我不需要订单,所以我不在乎是否有订单
a = dict(a=1, b=42)
my_func(**a)
因为他不知道口述是不被命令的(即使他应该知道)
2) 我认为,在一些争论的情况下,开销不会很大,因此有一个新的可能性来管理争论的好处将优于这个缺点
但是(从乔的回答来看)开销似乎不可忽略
[编辑2]:
这似乎是朝着这个方向发展的。因为字典不是按定义排序的。我认为这真的很简单。kwargs的要点是精确地处理那些未排序的形式参数。如果您确实知道顺序,则可以将其作为“正常”参数或
*args
接收
这是字典里的定义
CPython实现详细信息:键和值列在
非随机的任意顺序在Python中有所不同
实现,并取决于字典的插入历史
和删除
Python字典是整个语言工作方式的核心,因此它们得到了高度优化。添加排序将影响性能,并需要更多的存储和处理开销
你可能会遇到这样的情况,但我认为这比普通情况更为特殊。为非常热门的代码路径添加“以防万一”功能不是明智的设计决策
编辑:
仅供参考
>>> timeit.timeit(stmt="z = dict(x)", setup='x = ((("one", "two"), ("three", "four"), ("five", "six")))', number=1000000)
1.6569631099700928
>>> timeit.timeit(stmt="z = OrderedDict(x)", setup='from collections import OrderedDict; x = ((("one", "two"), ("three", "four"), ("five", "six")))', number=1000000)
31.618864059448242
这大约是构建小型“正常”大小字典的30倍速度差。OrderedDict是标准库的一部分,因此我不认为它会带来更多的性能。作为反驳,下面是一个例子,说明这可能会导致复杂的语义。这里有几个案例:
- 函数总是得到一个无序的字典
- 函数总是得到一个有序的字典-鉴于此,我们不知道顺序是否有任何意义,就好像用户传递无序的数据结构一样,顺序将是任意的,而数据类型意味着顺序
- 函数获取传入的任何内容-这似乎很理想,但并没有那么简单
假定,将此作为调用的一部分所得到的好处是丢失的——相反,只期望一个<代码>有序的DICT < /C>作为一个参数。
< P>如果函数的参数是相关的,名称和顺序都很重要,请考虑使用特定的数据结构或定义一个类来保存它们。很可能,您希望它们在代码中的其他位置一起出现,并可能定义使用它们的其他函数/方法。检索通过**kwargs传递的关键字参数的顺序对于我正在处理的特定项目非常有用。它是关于制作一种具有有意义尺寸的n-d numpy阵列(现在称为dimarray),对于地球物理数据处理特别有用 我在这里发布了一个带有示例的已开发问题:我认为这更像是为什么而不是为什么-关键字参数需要排序是一种罕见的情况,而且排序字典不像
dict
s那样核心,所以它不是那样做的。@Lattyware我想说这种需要很少,因为它不可用。如果我能依靠保留的关键字参数的顺序,我会经常使用该功能。@piokuc真的吗?好吧,不管怎样,它都会使关键字参数的语义变得非常混乱-参见我的答案。**kwargs
由于python 3.6是一个有序的dict
,因此关键字参数顺序被保留。请看这里:这是一种很糟糕的计时方式,timeit
模块的存在是有原因的。它既快又脏,可以测量经过的时间差。“很糟糕”吗?有一个系数是30。你应该回答“因为字典不是按定义排序的。”-我认为你把字典和哈希表搞混了。只是提醒我们,我们讨论的问题是“为什么Python的函数调用语义传入关键字参数不是按顺序排列的?”。例如,“为什么Python是按原样实现的”。哈希表是AFAIK中最快的字典实现。如果您知道一种实现有序字典的算法,它比哈希表更快(或者考虑到它在函数中的用例百分比,在某种意义上更慢),请告诉我们。这不是答案,因此应该删除。因此,他选择了(合理地)严格的问答形式。