【问题标题】:Is there a Python's defaultdict functionality available in LuaLua 中是否有 Python 的 defaultdict 功能?
【发布时间】:2014-09-06 06:26:38
【问题描述】:

Lua 中是否有类似于 Python 中的collections.defaultdict 的功能,可以自动处理不存在的关联数组键的默认值?

我希望下面的代码将 nil 设置为 v 而不是错误。所以基本上a[2](不存在的键)默认是table的一种方法:

a = {}
v = a[2][3] 

>>> PANIC: unprotected error in call to Lua API (main.lua:603: attempt to index field '?' (a nil value))

在 Python 中可以这样完成:

>>> import collections
>>> a = collections.defaultdict(dict)
>>> print a[2]
{}

【问题讨论】:

    标签: python lua defaultdict


    【解决方案1】:

    是否有 Lua 标准函数可以做到这一点?不,但是您可以使用元表轻松做到这一点。你甚至可以编写一个函数来创建这样的表:

    function CreateTableWithDefaultElement(default)
      local tbl = {}
      local mtbl = {}
      mtbl.__index = function(tbl, key)
        local val = rawget(tbl, key)
        return val or default
      end
      setmetatable(tbl, mtbl)
      return tbl
    end
    

    请注意,每个元素都将获得 same 默认值。因此,如果您将默认值设为表,则返回表中的每个“空”元素将有效地引用同一个表。如果这不是您想要的,您将不得不修改函数。

    【讨论】:

    • 这里为什么需要rawget()? __index() 函数只有在 table 没有请求的 key 时才会被调用吗?
    【解决方案2】:

    只是想我会分享我的代码版本,如果有人发现它需要与表、对象等兼容的版本。此外,与 Nicol 的解决方案相反,这实际上在表中创建了请求的条目。

    function defaultdict(default_value_factory)
        local t = {}
        local metatable = {}
        metatable.__index = function(t, key)
            if not rawget(t, key) then
                rawset(t, key, default_value_factory(key))
            end
            return rawget(t, key)
        end
        return setmetatable(t, metatable)
    end
    

    示例用法:

    d = defaultidct(function() return {} end)
    table.insert(d["people"], {"Bob", "The Builder"})
    
    names = defaultdict(function(key) return key end)
    print(names["bob"]) -- bob
    names["bob"] = "bob the builder"
    names["ashley"] = "ashley the fire princess"
    

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 2014-07-29
      • 2020-05-05
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 2019-10-05
      • 2010-11-28
      相关资源
      最近更新 更多