有没有办法简化所有可能(长度x高度)网格的创建?

发布于 2025-01-12 03:45:40 字数 1565 浏览 0 评论 0原文

这是我的 4x4 网格代码,可以更好地解释我的问题:

    #The "Duct-Tape" solution
    for box0 in range(0,2):
        for box1 in range(0,2):
            for box2 in range(0,2):
                for box3 in range(0,2):
                    for box4 in range(0,2):
                        for box5 in range(0,2):
                            for box6 in range(0,2):
                                for box7 in range(0,2): #0 = OutBag, 1 = InBag
                                    for box8 in range(0,2):
                                        for box9 in range(0,2):
                                            for box10 in range(0,2):
                                                for box11 in range(0,2):
                                                    for box12 in range(0,2):
                                                        for box13 in range(0,2):
                                                            for box14 in range(0,2):
                                                                for box15 in range(0,2):
                                                                    totalGrids.append([[box0,box1,box2,box3],
                                                                                         [box4,box5,box6,box7],
                                                                                         [box8,box9,box10,box11],
                                                                                         [box12,box13,box14,box15]])

What's a way to make this for a length x height size grid?

Here's my code for a 4x4 grid to better explain my problem:

    #The "Duct-Tape" solution
    for box0 in range(0,2):
        for box1 in range(0,2):
            for box2 in range(0,2):
                for box3 in range(0,2):
                    for box4 in range(0,2):
                        for box5 in range(0,2):
                            for box6 in range(0,2):
                                for box7 in range(0,2): #0 = OutBag, 1 = InBag
                                    for box8 in range(0,2):
                                        for box9 in range(0,2):
                                            for box10 in range(0,2):
                                                for box11 in range(0,2):
                                                    for box12 in range(0,2):
                                                        for box13 in range(0,2):
                                                            for box14 in range(0,2):
                                                                for box15 in range(0,2):
                                                                    totalGrids.append([[box0,box1,box2,box3],
                                                                                         [box4,box5,box6,box7],
                                                                                         [box8,box9,box10,box11],
                                                                                         [box12,box13,box14,box15]])

What's a way to make something like this for a length x height size grid?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小情绪 2025-01-19 03:45:40

这是使用二进制算术减少 for 循环的另一种方法:

totalGrids = []
for i in range(0, 1 << 16):
    totalGrids.append(
        [
            [(i >> j) & 1 for j in range(0, 4)], 
            [(i >> j) & 1 for j in range(4, 8)], 
            [(i >> j) & 1 for j in range(8, 12)], 
            [(i >> j) & 1 for j in range(12, 16)]
        ])
print(totalGrids[0])
print(totalGrids[1])
print(totalGrids[2])
print()
print(totalGrids[-3])
print(totalGrids[-2])
print(totalGrids[-1])

输出(前 3 个和最后 3 个元素):

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

[[1, 0, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
[[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

将其从 4 x 4 推广到 height x width,类似这样的东西应该可以工作:

height = 3
width = 5
totalGrids = []
for i in range(0, 1 << (height * width)):
    totalGrids.append(
        [[(i >> j) & 1 for j in range(k * width, (k + 1) * width)] for k in range(0, height)]
    )

这是对上述内容的解释。

  • 该矩阵具有 height x width 元素,将在这些元素中填充 0 和 1 的所有可能组合。例如,如果 height = 2 且 width = 4,则总共有 8 个元素,所需的 0 和 1 组合的一种排序是
0 0 0 0   0 0 0 0 (this is 0 in binary)
0 0 0 0   0 0 0 1 (this is 1 in binary)
0 0 0 0   0 0 1 0 (this is 2 in binary)
0 0 0 0   0 0 1 1 (this is 3 in binary)
...
0 0 0 0   1 1 1 1 (this is 15 in binary)
0 0 0 1   0 0 0 0 (this is 16 in binary)
0 0 0 1   0 0 0 1
0 0 0 1   0 0 1 0
0 0 0 1   0 0 1 1 (EXAMPLE VALUE USED BELOW)
...
0 0 1 0   0 0 0 0 (this is 32 in binary)
...
0 0 1 1   0 0 0 0 (this is 48 in binary)
...
1 1 1 1   1 1 1 1 (this is 255 = 2**8 - 1 in binary)

:只是从 0 到 2**8 - 1 的二进制值,可以在 range(0, 2**8) 中表示为 Python 整数。它们正是所需要的,现在唯一的问题是如何填充大小为 height x width 的 list 的 Python list

答案是使用二进制算术。让我们以 0 0 0 1 0 0 1 1 为例。我们可以在 Python 中将其指定为整数,即 i = 19

对于 8 的 1st 槽,我们希望使用示例中最右边的二进制位,即 1。我们可以使用 Python 的按位 & 运算通过 value = i & 来提取它。 1..应用 & 1 到任何整数都会有效地屏蔽除二进制个位数字之外的所有数字。

对于2nd槽,我们需要添加一个额外的步骤:

  • 首先,我们将位向右滑动1个位置(允许最右边的位从边缘掉落,这很好,因为我们已经处理过它并且不再需要它)使用Python的右移操作>>如下:value = i>>> 1..在二进制中,这会产生 0 0 0 0 1 0 0 1,即整数 9。右移运算符已将二进制双位中的位向右移动到二进制位中 -地方。
  • 接下来,我们可以使用与 1st 插槽相同的技术来屏蔽除个位之外的所有位:value = i & 1..
  • 我们可以简单地编写: value = (i >> 1) & ,而不是将上述作为两个单独的语句来执行。 1..

一般来说,对于第 j 个槽,我们可以通过编写以下代码从示例整数中提取第 j 位: j) & 1..

现在让我们看看循环中的关键逻辑:

[[(i >> j) & 1 for j in range(k * width, (k + 1) * width)] for k in range(0, height)]

它使用嵌套的列表理解首先在 range(0, height) 中的 k 上循环然后将 j 放入 range(k * width, (k + 1) * width) 中,并将上述按位表达式的结果放入 (i > ;> j) & 1 进入矩阵(或列表列表)中的每个连续元素。

最后,让我们再看一下代码中最外层的循环:

for i in range(0, 1 << (height * width)):

这使用了 Python 的按位左移操作<<,其作用与右移相反shift (>>) 的作用,即将1的位向左移动(height * width)二进制位置。由于每次向左移动都会导致数字的值加倍,因此我们的 left shift 表达式给出的结果与 2 ** (height * width) 相同,这正是您的问题正在寻找的 0/1 组合的数量。

因此,通过从 0 迭代到 2 **(高度 * 宽度),然后提取每个值的位并将其整理到该迭代矩阵的相应矩阵元素中,并将该矩阵附加到totalGrids 变量,我们最终构造一个具有所需属性的矩阵列表。

This is another way to do it with fewer for loops by using binary arithmetic:

totalGrids = []
for i in range(0, 1 << 16):
    totalGrids.append(
        [
            [(i >> j) & 1 for j in range(0, 4)], 
            [(i >> j) & 1 for j in range(4, 8)], 
            [(i >> j) & 1 for j in range(8, 12)], 
            [(i >> j) & 1 for j in range(12, 16)]
        ])
print(totalGrids[0])
print(totalGrids[1])
print(totalGrids[2])
print()
print(totalGrids[-3])
print(totalGrids[-2])
print(totalGrids[-1])

Output (first 3 and last 3 elements):

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

[[1, 0, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
[[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

To generalize this from 4 x 4 to height x width, something like this should work:

height = 3
width = 5
totalGrids = []
for i in range(0, 1 << (height * width)):
    totalGrids.append(
        [[(i >> j) & 1 for j in range(k * width, (k + 1) * width)] for k in range(0, height)]
    )

Here is an explanation of the above.

  • The matrix, which has height x width elements, is to be filled with every possible combination of 0s and 1s across these elements. As an example, if height = 2 and width = 4, then there are 8 elements in total, and one ordering of the required combinations of 0s and 1s is:
0 0 0 0   0 0 0 0 (this is 0 in binary)
0 0 0 0   0 0 0 1 (this is 1 in binary)
0 0 0 0   0 0 1 0 (this is 2 in binary)
0 0 0 0   0 0 1 1 (this is 3 in binary)
...
0 0 0 0   1 1 1 1 (this is 15 in binary)
0 0 0 1   0 0 0 0 (this is 16 in binary)
0 0 0 1   0 0 0 1
0 0 0 1   0 0 1 0
0 0 0 1   0 0 1 1 (EXAMPLE VALUE USED BELOW)
...
0 0 1 0   0 0 0 0 (this is 32 in binary)
...
0 0 1 1   0 0 0 0 (this is 48 in binary)
...
1 1 1 1   1 1 1 1 (this is 255 = 2**8 - 1 in binary)

These are just the binary values from 0 to 2**8 - 1 which can be expressed as Python integers in range(0, 2**8). They are exactly what is needed, and now the only question is how to populate a Python list of lists of size height x width.

The answer is to use binary arithmetic. Let's look at 0 0 0 1 0 0 1 1 as an example. We can specify this in Python as an integer, namely i = 19.

For the 1st slot of 8, we want to use the rightmost binary bit in our example, which is 1. We can extract this using Python's bitwise & operation by taking value = i & 1. Applying & 1 to any integer effectively masks off all but the binary ones-place digit.

For the 2nd slot, we need to add an additional step:

  • First we slide the bits to the right by 1 position (allowing the rightmost bit to fall off the edge, which is fine since we have already processed it and won't need it again) using Python's right shift operation >> as follows: value = i >> 1. In binary, this yields 0 0 0 0 1 0 0 1, which is the integer 9. The right-shift operator has moved the bit that was in the binary twos-place rightward into the binary ones-place.
  • Next, we can use the same technique as we did for the 1st slot to mask off all but the ones-place bit: value = i & 1.
  • Rather than do the above as two separate statements, we can simply write: value = (i >> 1) & 1.

In general, for the j'th slot, we can extract the j'th bit from our example integer by writing: value = (i >> j) & 1.

Now let's look at the key logic within the loop:

[[(i >> j) & 1 for j in range(k * width, (k + 1) * width)] for k in range(0, height)]

This uses a nested list comprehension to loop first over k in range(0, height) and then over j in range(k * width, (k + 1) * width), and to put the result of the above bitwise expression (i >> j) & 1 into each successive element in our matrix (or list of lists).

Finally, let's look again at the very outer loop in the code:

for i in range(0, 1 << (height * width)):

This uses Python's bitwise left shift operation <<, which does the opposite of what right shift (>>) does, namely to shift the bits of 1 to the left by (height * width) binary positions. Because each shift to the left causes a number to double in value, our left shift expression gives the same result as 2 ** (height * width), which is exactly the number of 0/1 combinations that your question is seeking.

So, by iterating from 0 to 2 ** (height * width), then extracting and collating the bits of each value into the corresponding matrix elements for that iteration's matrix, and appending that matrix to the totalGrids variable, we ultimately construct a list of matrices with the required properties.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文