gpt4 book ai didi

python - 使用设置重新排列 for 循环的顺序

转载 作者:太空宇宙 更新时间:2023-11-03 11:48:58 25 4
gpt4 key购买 nike

我正在使用具有以下结构/条目的数组(用于量子信息游戏的硕士项目);第一列条目 {0,1},第二列 {0,1},第三列 {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

现在我希望能够轻松地选择列中的条目开始计数的顺序。 (在其上方从右列到左列。)

例如,假设我希望从第 1 列开始计数,然后是第 3 列,然后是第 4 列,最后是第 2 列。我可以通过置换函数中的 for-loops 来得到它:

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,[a,b,x,y],axis=0)
res = np.reshape(res,(-1,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, 2, 3, 1]) 获得作为示例给出的输出。此外,现在可以通过遍历 itertools.permutations(range(4)) 轻松获得所有可能的排列。


作为奖励,这里有一种方法可以仅使用 Numpy(对于较大的 d)使此操作执行得更快:

def make_games_np(d=3, perm=[3,2,1,0]):
entries = [range(2),
range(2),
range(2**(d-1)),
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, 0, n+1)

order = list(perm)[::-1] + [n]
games = entries_grid.transpose(*order).reshape(-1, n)

return games

关于python - 使用设置重新排列 for 循环的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32665755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com