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! ---'
我想在 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! ---'