Python-在二维数组中移动元素?

Python-在二维数组中移动元素?,python,arrays,Python,Arrays,给定这个2D数组- [0,0,-1]、[0,0,-2]、[0,0,0]、[0,0,-3]、[0,0,0]] 如何用Python编写每次调用时都会移动一次的代码?但是,如果达到正值,则必须停止 所以我得到了这样的东西 [0,0,0],[0,0,-1],[0,0,-2],[0,0,-3],[0,0,0]] 这就是我所拥有的。它适用于条件1,但不适用于条件2。我可以调整什么使条件2也起作用 # Condition 1 - Works data = [[0, 0, -1], [0, 0, -2], [0

给定这个2D数组-

[0,0,-1]、[0,0,-2]、[0,0,0]、[0,0,-3]、[0,0,0]]

如何用Python编写每次调用时都会移动一次的代码?但是,如果达到正值,则必须停止

所以我得到了这样的东西

[0,0,0],[0,0,-1],[0,0,-2],[0,0,-3],[0,0,0]]

这就是我所拥有的。它适用于条件1,但不适用于条件2。我可以调整什么使条件2也起作用

# Condition 1 - Works
data = [[0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0], [0, 0, 0]]
expected = [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0]] # My Results. 

# Condition 2 - Does Not Work
data = [[0, 0, -1], [0, 0, -2], [0, 0, 0], [0, 0, 3], [0, 0, 0]]
expected = [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0]] # This is what I want to get. (But it doesn't work)

rows = len(data)

if data[-1][-1] == 0:
    count = rows-1
    while count > 0:
        data[count][-1] = data[count-1][-1]
        count -= 1
    data[0][-1] = 0

print(data)
print(expected)
这就是我目前得到的。我想获得上面截取的代码中列出的条件2的预期值:

条件2结果: [0,0,0],[0,0,-1],[0,0,-2],[0,0,0],[0,0,-3]

谢谢

更新@Furas: 像这样的东西来找到正值位置

   possitive_value = []
    for i in range(len(data)):
        if data[i][-1] > 0:
            possitive_value.append(i, -1)

我认为您必须找到第一个正值,并将其位置用作

编辑:我将名称
count
更改为
last
,以使其更具可读性

# --- function ---

def move(data):

    rows = len(data)

    # - find positive -

    for x in range(rows):
        if data[x][-1] > 0:
            rows = x # use its position as `rows`
            break    # don't seach other positiove values 

    # - star moving -

    # set "last" checked row
    last = rows-1

    # check "last" row
    if data[last][-1] == 0:

        # move previous values
        while last > 0:
            data[last][-1] = data[last-1][-1]
            last -= 1

        # put 0 in first place    
        data[0][-1] = 0

# --- tests ---

examples = [
  {
    # Condition 1 - Works
    'data': [[0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0], [0, 0, 0]],
    'expected': [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0]], # My Results. 
  },
  {
    # Condition 2 - Works
    'data': [[0, 0, -1], [0, 0, -2], [0, 0, 0], [0, 0, 3], [0, 0, 0]],
    'expected': [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0]], # This is what I want to get. (But it doesn't work)
  }
]

for example in examples:
    data = example['data']
    expected = example['expected']

    print('  before:', data)
    move(data)
    print('   after:', data)
    print('expected:', expected)
    print(' correct:', data == expected)
    print('---')
def move(data):

    rows = len(data)

    # - find positive -

    for x in range(rows):
        if data[x][-1] > 0:
            rows = x # use its position as `rows`
            break    # don't seach other positiove values 

    # - star moving -

    # set "last" checked row
    last = rows-1

    # check "last" row
    if data[last][-1] == 0:

        # move previous values
        for pos in range(last, 0, -1): # range with reversed order
            data[pos][-1] = data[pos-1][-1]

        # put 0 in first place    
        data[0][-1] = 0
结果:

  before: [[0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0], [0, 0, 0]]
   after: [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0]]
expected: [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0]]
 correct: True
---
  before: [[0, 0, -1], [0, 0, -2], [0, 0, 0], [0, 0, 3], [0, 0, 0]]
   after: [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0]]
expected: [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0]]
 correct: True
---

编辑:

顺便说一句:而不是
您可以使用
for
和反向
范围()

# --- function ---

def move(data):

    rows = len(data)

    # - find positive -

    for x in range(rows):
        if data[x][-1] > 0:
            rows = x # use its position as `rows`
            break    # don't seach other positiove values 

    # - star moving -

    # set "last" checked row
    last = rows-1

    # check "last" row
    if data[last][-1] == 0:

        # move previous values
        while last > 0:
            data[last][-1] = data[last-1][-1]
            last -= 1

        # put 0 in first place    
        data[0][-1] = 0

# --- tests ---

examples = [
  {
    # Condition 1 - Works
    'data': [[0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0], [0, 0, 0]],
    'expected': [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, -3], [0, 0, 0]], # My Results. 
  },
  {
    # Condition 2 - Works
    'data': [[0, 0, -1], [0, 0, -2], [0, 0, 0], [0, 0, 3], [0, 0, 0]],
    'expected': [[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0]], # This is what I want to get. (But it doesn't work)
  }
]

for example in examples:
    data = example['data']
    expected = example['expected']

    print('  before:', data)
    move(data)
    print('   after:', data)
    print('expected:', expected)
    print(' correct:', data == expected)
    print('---')
def move(data):

    rows = len(data)

    # - find positive -

    for x in range(rows):
        if data[x][-1] > 0:
            rows = x # use its position as `rows`
            break    # don't seach other positiove values 

    # - star moving -

    # set "last" checked row
    last = rows-1

    # check "last" row
    if data[last][-1] == 0:

        # move previous values
        for pos in range(last, 0, -1): # range with reversed order
            data[pos][-1] = data[pos-1][-1]

        # put 0 in first place    
        data[0][-1] = 0

顺便说一句:两个版本都会移动原始数据中的项目(
“就地”
),因此它们不需要
返回数据

这里有一个变体,一个可以调用的函数,每次都会将数据移动一次。从你的问题中我不完全清楚这是否是你想要的行为

import numpy as np

def shift_data(data):
    ele_idx = [i  for i,x in enumerate(data) if x != [0,0,0]]
    zero_idx = [i for i,x in enumerate(data) if x == [0,0,0] and i != 0]

    if max(np.diff(ele_idx)) == 1 or max(np.diff([i for i,x in enumerate(data) if x == [0,0,0]])) == 1:#things are consecutive
        data.insert(0,data.pop(-1))
    else:
        tt = [l for l in data[ele_idx[0]:zero_idx[0]+1]]
        tt.insert(0,tt.pop(-1))
        data = data[:ele_idx[0]] + tt + data[zero_idx[0]+1:]

    return data

data = [[0, 0, -1], [0, 0, 0], [0, 0, -2], [0, 0, 0], [0, 0, 3]]
print(data)
for _ in range(0,6):
    data = shift_data(data)
    print(data)
此代码输出:

[[0, 0, -1], [0, 0, 0], [0, 0, -2], [0, 0, 0], [0, 0, 3]]
[[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 0], [0, 0, 3]]
[[0, 0, 0], [0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3]]
[[0, 0, 3], [0, 0, 0], [0, 0, 0], [0, 0, -1], [0, 0, -2]]
[[0, 0, -2], [0, 0, 3], [0, 0, 0], [0, 0, 0], [0, 0, -1]]
[[0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0], [0, 0, 0]]
[[0, 0, 0], [0, 0, -1], [0, 0, -2], [0, 0, 3], [0, 0, 0]]

你能为每一次迭代详述你的例子吗。。。不知何故,我无法理解您想要实现上述预期结果的内容和方式。我的意思是在我的结果(had**)中加粗文本。希望现在更清楚了。我的条件1是功能性的,但我也需要条件2才能工作。所以每次我调用它,它都会向末尾移动一次,除非它们的值大于0。希望这更清楚。谢谢(:原始版本正在移动范围
(第一行,最后一行)
(换句话说
(0,行)
)。正确的版本应首先找到正定值,然后在范围
(0,行,带正-1)中开始移动
感谢您的响应。我仍然有点不确定这会是什么样子。我基本上希望它在达到正值时停止移动元素。(如条件2)。我将指定列号,在上面的示例中为[-1]。如果您有时间,请按此操作。@furas。代码片段(如您之前提供的)非常感谢。谢谢(:非常感谢!将在早上实现此功能,希望它能正常工作。此版本中的最后一行不一定是0。它也可以是正值(3),因此我假设我不再需要if语句,因为程序将在它前面的行停止?
if data[last][1]==0
检查在
3
之前是否有
0
(第一个正值)。如果有ie.
-4
,则无需移动。或者,即使有
-4
,也可能必须移动。如果有
-4
,则可以删除此
。在这种情况下,0保持不变。我想我感到困惑了。谢谢
print()
内部函数,查看代码中发生了什么-