lua 中的并行迭代

parallel iteration in lua

我想在 Lua 中并行遍历多个表。我可以这样做:

for i in range(#table1)
  pprint(table1[i])
  pprint(table2[i])
end

但我更喜欢 python 的 zip:

for elem1, elem2 in zip(table1, table2):
  pprint(elem1)
  pprint(elem2)
end

标准 Lua 中是否有这样的东西(或者至少在 torch 附带的任何东西中?)。

如果你想要 Lua 中类似于某些 Python 功能的东西,你应该查看 Penlight first. For this specific case there is the seq.zip function. It seems Penlight 与 Torch 一起安装,但你也可以通过LuaRocks(同样与至少一个 Torch 发行版捆绑在一起)。

无论如何,Penlight中的seq.zip功能只支持压缩两个序列。这是一个应该表现得更像 Python 的 zip 的版本,即允许多于(或少于)两个序列:

local zip
do
  local unpack = table.unpack or unpack
  local function zip_select( i, var1, ... )
    if var1 then
      return var1, select( i, var1, ... )
    end
  end

  function zip( ... )
    local iterators = { n=select( '#', ... ), ... }
    for i = 1, iterators.n do
      assert( type( iterators[i] ) == "table",
              "you have to wrap the iterators in a table" )
      if type( iterators[i][1] ) ~= "number" then
        table.insert( iterators[i], 1, -1 )
      end
    end
    return function()
      local results = {}
      for i = 1, iterators.n do
        local it = iterators[i]
        it[4], results[i] = zip_select( it[1], it[2]( it[3], it[4] ) )
        if it[4] == nil then return nil end
      end
      return unpack( results, 1, iterators.n )
    end
  end
end

-- example code (assumes that this file is called "zip.lua"):
local t1 = { 2, 4, 6, 8, 10, 12, 14 }
local t2 = { "a", "b", "c", "d", "e", "f" }
for a, b, c in zip( {ipairs( t1 )}, {ipairs( t2 )}, {io.lines"zip.lua"} ) do
  print( a, b, c )
end
--------------------------------------------------------------------------------
-- Python-like zip() iterator
--------------------------------------------------------------------------------

function zip(...)
  local arrays, ans = {...}, {}
  local index = 0
  return
    function()
      index = index + 1
      for i,t in ipairs(arrays) do
        if type(t) == 'function' then ans[i] = t() else ans[i] = t[index] end
        if ans[i] == nil then return end
      end
      return unpack(ans)
    end
end

--------------------------------------------------------------------------------
-- Example use:
--------------------------------------------------------------------------------

a = {'a','b','c','d'}
b = {3,2,1}
c = {7,8,9,10,11}

for a,b,c,line in zip(a,b,c,io.lines(arg[0])) do
  print(a,b,c,line)
end

print '\n--- Done! ---'