python – 使用设置重新排列for循环的顺序
发布时间:2020-12-20 13:53:17 所属栏目:Python 来源:网络整理
导读:我正在使用具有以下类型的结构/条目的数组(对于量子信息游戏中的主人项目); 第1列条目{0,1},第2列{0,第3列{0,2 **(d-1)},最后一列{0,d-1}. 如下d = 3: G = [[0 0 0 0] [0 0 0 1] [0 0 0 2] [0 0 1 0] [0 0 1 1] [0 0 1 2] [0 0 2 0] [0 0 2 1] [0 0 2 2] [0
我正在使用具有以下类型的结构/条目的数组(对于量子信息游戏中的主人项目);
第1列条目{0,1},第2列{0,第3列{0,2 **(d-1)},最后一列{0,d-1}. 如下d = 3: G = [[0 0 0 0] [0 0 0 1] [0 0 0 2] [0 0 1 0] [0 0 1 1] [0 0 1 2] [0 0 2 0] [0 0 2 1] [0 0 2 2] [0 0 3 0] [0 0 3 1] [0 0 3 2] [0 1 0 0] [0 1 0 1] [0 1 0 2] [0 1 1 0] [0 1 1 1] [0 1 1 2] [0 1 2 0] [0 1 2 1] [0 1 2 2] [0 1 3 0] [0 1 3 1] [0 1 3 2] [1 0 0 0] [1 0 0 1] [1 0 0 2] [1 0 1 0] [1 0 1 1] [1 0 1 2] [1 0 2 0] [1 0 2 1] [1 0 2 2] [1 0 3 0] [1 0 3 1] [1 0 3 2] [1 1 0 0] [1 1 0 1] [1 1 0 2] [1 1 1 0] [1 1 1 1] [1 1 1 2] [1 1 2 0] [1 1 2 1] [1 1 2 2] [1 1 3 0] [1 1 3 1] [1 1 3 2]] 我正在使用以下函数来构建此数组: def games(d = 3): res = np.empty(0).astype(int) for a in range(2): for b in range(2): for x in range(2**(d-1)): for y in range(d): res = np.append(res,[a,b,x,y],axis=0) res = np.reshape(res,(-1,4)) return res 现在我想做的是,可以轻松选择列中的条目开始计数的顺序. (从左侧的右侧列开始.) 例如,假设Id像第一列开始计数,然后是第3列,然后是第4列,最后是第2列.我可以通过置换函数中的for循环来获得这个: def games(d = 3): res = np.empty(0).astype(int) for b in range(2): for y in range(d): for x in range(2**(d-1)): for a in range(2): res = np.append(res,4)) return res 这使: G= [[0 0 0 0] [1 0 0 0] [0 0 1 0] [1 0 1 0] [0 0 2 0] [1 0 2 0] [0 0 3 0] [1 0 3 0] [0 0 0 1] [1 0 0 1] [0 0 1 1] [1 0 1 1] [0 0 2 1] [1 0 2 1] [0 0 3 1] [1 0 3 1] [0 0 0 2] [1 0 0 2] [0 0 1 2] [1 0 1 2] [0 0 2 2] [1 0 2 2] [0 0 3 2] [1 0 3 2] [0 1 0 0] [1 1 0 0] [0 1 1 0] [1 1 1 0] [0 1 2 0] [1 1 2 0] [0 1 3 0] [1 1 3 0] [0 1 0 1] [1 1 0 1] [0 1 1 1] [1 1 1 1] [0 1 2 1] [1 1 2 1] [0 1 3 1] [1 1 3 1] [0 1 0 2] [1 1 0 2] [0 1 1 2] [1 1 1 2] [0 1 2 2] [1 1 2 2] [0 1 3 2] [1 1 3 2]] 在函数中置换for循环的顺序是有效的,但是我必须编写24种不同的情况来覆盖所有的排列.任何人都知道一般来说会有更好的解决方案/方法吗? 解决方法
你正在计算的东西被称为“笛卡尔积”,并且偶然需要来自标准库的
itertools module具有在没有所有显式循环的情况下构造它的功能.通过置换给itertools.product的参数的顺序,确定列计数顺序.剩下要做的唯一事情是将列重新排列回所需的顺序,但这可以通过Numpy轻松完成.
import itertools def make_games(d=3,perm=[3,2,1,0]): entries = [range(2),range(2),range(2**(d-1)),range(d)] # Python3 compatibility entries = [list(entry) for entry in entries] # Cartesian product with columns count-order by `perm` permuted_entries = [entries[px] for px in perm[::-1]] games_list = list(itertools.product(*permuted_entries)) # Move the columns around to the original ordering sorter = np.argsort(perm[::-1]) games = np.take(games_list,sorter,axis=1) return games 现在可以通过调用make_games(3,[0,3,1])来获得作为示例给出的输出.此外,现在可以通过循环遍历itertools.permutations(范围(4))轻松获得所有可能的排列. 作为奖励,这里有一种方法可以让Numpy(对于更大的d)更快地执行此操作: def make_games_np(d=3,range(d)] # Python3 compatability entries = [list(entry) for entry in entries] n = len(entries) entries_grid = np.array(np.meshgrid(*entries,indexing='ij')) entries_grid = np.rollaxis(entries_grid,n+1) order = list(perm)[::-1] + [n] games = entries_grid.transpose(*order).reshape(-1,n) return games (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |