Dictionary Julia-迭代字典中的键组合

Dictionary Julia-迭代字典中的键组合,dictionary,iterator,julia,Dictionary,Iterator,Julia,有没有一种巧妙的方法可以迭代字典中的键组合 我的字典的值如下: [1] => [1,2], [2,3] => [15], [3] => [6,7,8], [4,9,11] => [3], ... 我需要做的是获取长度为1:n的所有键组合,其中n可能是fx 3 就像上面的例子一样,我想迭代 [[1], [3], [2,3], [[1],[1,2]], [[3],[2,3]], [4,9,11]] 我知道我可以收集密钥,但是我的字典相当大,我正在重新设计整个算法,因为当

有没有一种巧妙的方法可以迭代字典中的键组合

我的字典的值如下:

[1] => [1,2], [2,3] => [15], [3] => [6,7,8], [4,9,11] => [3], ... 
我需要做的是获取长度为
1:n
的所有键组合,其中
n
可能是fx 3

就像上面的例子一样,我想迭代

[[1], [3], [2,3], [[1],[1,2]], [[3],[2,3]], [4,9,11]]
我知道我可以收集密钥,但是我的字典相当大,我正在重新设计整个算法,因为当代码> n>3 < /代码>时,它开始疯狂地交换,大大降低了效率


tl;dr有没有一种方法可以从字典中创建组合迭代器,而不必收集字典?

下面是一个简单的实现,它尝试在浏览字典时最小化位。此外,它还使用OrderedDict,因此保持键索引是有意义的(因为DICT不能保证每次都进行一致的键迭代,因此键索引是有意义的)

这比你目前拥有的更有效吗?最好将代码放在函数中,或者将其转换为Julia任务,每次迭代生成下一个键集

---更新---

使用中任务中有关迭代器的答案

改进的迭代器版本是:

function keysubsets(n,d)
  Task() do
    od = OrderedDict(d)
    sv = map(length,keys(od))        # store length of keys for quicker calculations
    maxmaxlen = sum(sv)              # maximum total elements in good key
    for maxlen=1:min(n,maxmaxlen)    # replace maxmaxlen with lower value if too slow
      gsets = Vector{Vector{Int}}()  # hold good sets of key _indices_
      for curlen=1:maxlen
        foreach(x->push!(gsets,x),(x for x in subsets(collect(1:n),curlen) if sum(sv[x])==maxlen))
      end
      # indmatrix is necessary to run through keys once in next loop
      indmatrix = zeros(Bool,length(od),length(gsets))
      for i=1:length(gsets)              for e in gsets[i]
          indmatrix[e,i] = true
        end
      end
      # gkeys is the vector of vecotrs of keys i.e. what we wanted to calculate
      gkeys = [Vector{Vector{Int}}() for i=1:length(gsets)]
      for (i,k) in enumerate(keys(od))
        for j=1:length(gsets)
          if indmatrix[i,j]
            push!(gkeys[j],k)
          end
        end
      end
      # do something with each set of good keys
      foreach(x->produce(x),gkeys)
    end
  end
end
现在可以通过这种方式(在运行另一个StackOverflow应答中的代码后)在组合大小为4的所有密钥子集上进行迭代:

(需要从链接的堆栈溢出答案中定义NewTask)

function keysubsets(n,d)
  Task() do
    od = OrderedDict(d)
    sv = map(length,keys(od))        # store length of keys for quicker calculations
    maxmaxlen = sum(sv)              # maximum total elements in good key
    for maxlen=1:min(n,maxmaxlen)    # replace maxmaxlen with lower value if too slow
      gsets = Vector{Vector{Int}}()  # hold good sets of key _indices_
      for curlen=1:maxlen
        foreach(x->push!(gsets,x),(x for x in subsets(collect(1:n),curlen) if sum(sv[x])==maxlen))
      end
      # indmatrix is necessary to run through keys once in next loop
      indmatrix = zeros(Bool,length(od),length(gsets))
      for i=1:length(gsets)              for e in gsets[i]
          indmatrix[e,i] = true
        end
      end
      # gkeys is the vector of vecotrs of keys i.e. what we wanted to calculate
      gkeys = [Vector{Vector{Int}}() for i=1:length(gsets)]
      for (i,k) in enumerate(keys(od))
        for j=1:length(gsets)
          if indmatrix[i,j]
            push!(gkeys[j],k)
          end
        end
      end
      # do something with each set of good keys
      foreach(x->produce(x),gkeys)
    end
  end
end
julia> nt2 = NewTask(keysubsets(4,od))
julia> collect(nt2)
10-element Array{Array{Array{Int64,1},1},1}:
 Array{Int64,1}[[1]]          
 Array{Int64,1}[[3]]          
 Array{Int64,1}[[2,3]]        
 Array{Int64,1}[[1],[3]]      
 Array{Int64,1}[[4,9,11]]     
 Array{Int64,1}[[1],[2,3]]    
 Array{Int64,1}[[2,3],[3]]    
 Array{Int64,1}[[1],[4,9,11]] 
 Array{Int64,1}[[3],[4,9,11]] 
 Array{Int64,1}[[1],[2,3],[3]]