【问题标题】:Create lists with 3 levels, containing every combination of sub list(s) values创建具有 3 个级别的列表,包含子列表值的每个组合
【发布时间】:2018-11-23 01:23:29
【问题描述】:

我目前遇到以下问题(我在这里找不到真正适合这个的解决方案):

我有三个列表 a = [a, b, c]b = [1, 2, 3]c = [0.1, 0.2, 0.3]

我想创建一个列表列表(也许我应该使用 numpy 数组?),其中包含这些列表之间的所有组合,但是每个子列表中的每个元素也都在 bruce-force 中迭代模式,从而生成以下内容:

mylist = [[[a, 1, 0.1], [b, 1, 0.1], [c, 1, 0.1]], [[a, 1, 0.1], [b, 1, 0.1], [c, 1, 0.2]], ... [[a, 2, 0.3], [b, 3, 0.3], [c, 1, 0.1]], ... [[a, 1, 0.3], [b, 1, 0.3], [c, 1, 0.3]], ... [[a, 3, 0.3], [b, 1, 0.3], [c, 3, 0.1]] ... [[a, 3, 0.3], [b, 3, 0.3], [c, 3, 0.3]]]

我很欣赏这将等同于一个非常大的列表(很高兴被告知更好的方法!),但我实际上需要一个包含每个子列表的三维列表,例如mylist[0],作为包含单个子列表参数(例如,[[a, 3, 0.3], [b, 3, 0.3], [c, 3, 0.3]] 的列表传递给将它们用作输入的算法。这个 3-D 列表有效地形成了需要“搜索”的整个参数空间。因此,您可以看到以下组合示例的原因:

[[a, 1, 0.3], [b, 2, 0.3], [c, 2, 0.3]], [[a, 3, 0.1], [b, 1, 0.3], [c, 2, 0.1]]

很重要,因为它们是算法输入的唯一参数。

非常感谢您对此提供任何指导,谢谢。

【问题讨论】:

  • 欢迎来到 StackOverflow!那么,您尝试过什么?
  • 输出维度是多少?
  • @kevinkayaks,输出维度如下:
  • ` x = [[[a],[0],[0.1]],[[a],[0],[0.1]],[[a],[0],[ 0.1]]], y = 以上的所有组合`。那有意义吗?所以 3 个维度,其中 y 等于上述行的所有组合。
  • @Andreas 我曾尝试为每个列表使用递归循环,然后使用带有排列的 iterools,但无法按照上述方式获得正确的输出。

标签: python-3.x python-2.7 list numpy itertools


【解决方案1】:

生成器似乎是一种不错的方法,可以避免内存混乱。

import itertools as it
bc=list(it.product(b,c)) 
#[(1, 0.1), (1, 0.2), (1, 0.3), (2, 0.1), (2, 0.2), (2, 0.3), (3, 0.1), (3, 0.2), (3, 0.3)]
res = ([[u,*v] for u,v in zip(a,bc3)] for bc3 in it.product(*[bc]*3))

然后您可以使用以下命令扫描您的空间:

 for list_of_list in res : 
    #compute  list_of_list

第一个值:

In [49]: next(res) 
Out[49]: [['a', 1, 0.1], ['b', 1, 0.1], ['c', 1, 0.1]] 
In [50]: next(res) 
Out[50]: [['a', 1, 0.1], ['b', 1, 0.1], ['c', 1, 0.2]]

您可以通过arr = np.array(list(res),dtype=object) 获取数组。它的形状是 (729,3,3)。

【讨论】:

  • @Ryan 这是最好的答案。谢谢 B.M.,我从中学到了。
  • @kevinkayaks stackoverflow 礼节条款 如果它比以前发布的答案更好,是否可以更改答案?
  • @B. M. 效果很好,而且更优雅。谢谢。
  • @Ryan 的人这样做。据我所知,这不是什么大不了的事。大概它会帮助那些正在寻找未来方法的人选择最好的方法。
【解决方案2】:
import numpy as np 
import itertools as it
a = ['a', 'b', 'c']
b = [1, 2, 3]
c = [0.1, 0.2, 0.3]
l = np.array(np.meshgrid(a,b,c)).T
l = l.reshape(l.size//3,3)
subs = [[list(x) for x in l if x[0]==val] for val in a]
list(list(x) for x in it.product(*subs))

试试这个。它以一种明显的方式推广到a,b,c,d,...

也就是说,你很快就会耗尽内存。

【讨论】:

  • 我不认为这正是我想要的。例如,每个 X(“行”)维度应包含以下内容:[[a, 1, 0.1],[b, 1, 0.1][c, 1, 0.2]],所有后续行以迭代方式包含每个子列表的所有组合。这样list = [[[],[],[]],[[[],[],[]]] 和每个子列表都会遍历列表 b 和 c 中可能值之间的所有可能组合。在输出中,每一行都应包含列表 a 中值 a、b、c 的这些组合。我希望我没有太困惑!
  • 是的,我尝试了itertools.combinationsitertools.permutations,感谢以上内容。是的,内存是个问题,虽然我暂时忽略了这个问题以进行实验。正如@Red Cricket 首先回答的那样(我没有明确要求最优雅的解决方案),我必须接受他的回答,但会赞成这个答案(它会接受我的投票,但由于我的超级新手而不会明显发布地位)。再次感谢。
  • 关于内存问题的上下文。此列表用于生成包含强化学习参数组合的动作空间。因此,理想情况下,在 a、b、c、d 等数百万个组合的情况下,扩展 RL 环境显然需要大量内存。
猜你喜欢
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多