【问题标题】:Python: Loop through a 2D list based on the indices in the listPython:根据列表中的索引循环遍历二维列表
【发布时间】:2021-05-18 07:43:25
【问题描述】:

我有这个清单:

ls = [[0, [1, 5], [], 'A'],
      [1, [0, 2, 4], [], 'B'],
      [2, [3, 1], [], 'X'],
      [3, [2], [], 'C'],
      [4, [1], [], 'D'],
      [5, [0], [], 'E']]

我想遍历这个列表,从最后一项为“X”的行开始。在该行中,倒数第二项应为 0。之后,我想遍历同一行(第 3 行和第 1 行)第二列中显示的行,在这些行中,倒数第二项应为 1。然后我遍历第 0 行和第 4 行,倒数第二个项目应该是 2(此时无需遍历第 2 行,因为它已经被遍历了)。该迭代一直持续到整个倒数第二列被填满。所以输出应该是:

[[0, [1, 5], 2, 'A'],
 [1, [0, 2, 4], 1, 'B'],
 [2, [3, 1], 0, 'X'],
 [3, [2], 1, 'C'],
 [4, [1], 2, 'D'],
 [5, [0], 3, 'E']]

我尝试过这样做:

def foo(data):
    new_data = data
    for subls in new_data:
        if subls[3] == "X":
            start = subls[1]
            subls[2] = 0
    num = 1
    for num, item in enumerate(start):
        new_data[item][2] = num
        new_start = list(new_data[n][1] for n, i in enumerate(new_data))
        start = new_start
    num += 1
    return new_data

f = foo(ls)
for a in f:
    print(a)

但我只得到:

[0, [1, 5], [], 'A']
[1, [0, 2, 4], 1, 'B']
[2, [3, 1], 0, 'X']
[3, [2], 0, 'C']
[4, [1], [], 'D']
[5, [0], [], 'E']

我怎样才能做到这一点?

编辑@SaltySoda

起初这似乎可行,但当我尝试此列表时:

ls = [[0, [1, 7, 8, 9], [], 'E'],
        [1, [0, 2, 10, 11], [], 'C'],
        [2, [1, 3, 12, 13], [], 'C'],
        [3, [2, 4, 14, 15], [], 'C'],
        [4, [3, 5, 16, 17], [], 'C'],
        [5, [4, 6, 18, 19], [], 'C'],
        [6, [5, 20, 21, 22], [], 'E'],
        [7, [0], [], '-'],
        [8, [0], [], '-'],
        [9, [0], [], '-'],
        [10, [1], [], '-'],
        [11, [1], [], '-'],
        [12, [2], [], '-'],
        [13, [2], [], '-'],
        [14, [3], [], '-'],
        [15, [3], [], '-'],
        [16, [4], [], '-'],
        [17, [4], [], '-'],
        [18, [5], [], 'X'],
        [19, [5], [], '-'],
        [20, [6], [], '-'],
        [21, [6], [], '-'],
        [22, [6], [], '-']]

上面写着:

a[2] = a[2] - 1
TypeError: unsupported operand type(s) for -: 'list' and 'int'

您能否解释一下为什么会发生这种情况以及如何修复此错误?

【问题讨论】:

  • 为什么我们需要从第三行开始。有什么具体原因吗?
  • @Roy 是的,我总是必须从最后一项为“X”的行开始。这是因为我想知道另一行有多少索引“远离”这一行。
  • 是否只有一行将X 作为最后一项?最后肯定会有一排带“X”的吗?
  • @Roy 是的,只有一行的最后一项是 X。

标签: python list loops


【解决方案1】:

试试这个:

def foo(data):
    num=2
    new_data = data
    for lists in new_data:
        if lists[3]=="X":
            break
        else:
            lists[2]=num
            num-=1
            ls2.append(lists)
            #ls.remove(lists)
    for times in ls2:
        ls.remove(times)
    
    
    
    x=0
    for lss in new_data:
        lss[2]=x
        x+=1
        ls2.append(lss)
    return ls
    
ls = [[0, [1, 5], [], 'A'],
      [1, [0, 2, 4], [], 'B'],
      [2, [3, 1], [], 'X'],
      [3, [2], [], 'C'],
      [4, [1], [], 'D'],
      [5, [0], [], 'E']]
ls2 = [] #== list where the elements are added
f = foo(ls)
for new_datas in ls2:
    print(new_datas)
    

【讨论】:

    【解决方案2】:

    我会做这样的事情。首先通过这个函数获取以'X'结尾的行。

    def get_row_X_index(lst):
        for i in range(len(lst)):
            if lst[i][-1] == 'X':
                return i
    

    然后遍历整个列表,并通过测量与末尾包含'X' 的行的距离来填充每行的倒数第二个值。

    for i in range(len(ls)):
        ls[i][-2] = abs(X_row_index-i)
    

    完整代码:

    ls = [[0, [1, 5], [], 'A'],
          [1, [0, 2, 4], [], 'B'],
          [2, [3, 1], [], 'X'],
          [3, [2], [], 'C'],
          [4, [1], [], 'D'],
          [5, [0], [], 'E']]
    
    
    def get_row_X_index(lst):
        for i in range(len(lst)):
            if lst[i][-1] == 'X':
                return i
    
    X_row_index = get_row_X_index(ls)
    print(X_row_index)
    
    for i in range(len(ls)):
        ls[i][-2] = abs(X_row_index-i)
    
    print(ls)
    

    打印出来:

    [[0, [1, 5], 2, 'A'], 
    [1, [0, 2, 4], 1, 'B'], 
    [2, [3, 1], 0, 'X'], 
    [3, [2], 1, 'C'], 
    [4, [1], 2, 'D'], 
    [5, [0], 3, 'E']]
    

    【讨论】:

      【解决方案3】:
      def foo(data, rows, num):
          next_rows = []
          next_num = num + 1
          for row in rows:
              if data[row][2]:
                  continue
              else:
                  next_rows.extend(data[row][1])
                  data[row][2] = num
          return data, next_rows, next_num
      
      
      def foo_whole(data):
          rows = []
          num = 1
          for subls in data:
              if subls[3] == "X":
                  rows = [subls[0]]
          for subls in data:
              if not subls[2]:
                  data, rows, num = foo(data, rows, num)
          for a in data:
              a[2] = a[2] - 1
          return data
      
      
      if __name__ == '__main__':
          old_data = [[0, [1, 5], [], 'A'],
                      [1, [0, 2, 4], [], 'B'],
                      [2, [3, 1], [], 'X'],
                      [3, [2], [], 'C'],
                      [4, [1], [], 'D'],
                      [5, [0], [], 'E']]
          new_data = foo_whole(old_data)
          for a in new_data:
              print(a)
      

      【讨论】:

      • 嗨,你能解释一下吗?它是如何工作的?
      • 关于foo:这是最重要的部分,你输入'data'和你想改变的'rows',上面所有行应该是'num'。它改变数据[ row][2] 到 'num' 并从 data[row][1] 中获取 "next_num" 然后恢复到 'next_rows'
      • 关于 foo_whole:
      • stackoverflow 限制编辑率,如果你还有疑问,明天我会回答你!关于 foo_whole:1.你得到 'row' 其中 data[row][3] 是 'X' 2.设置初始数字为1(开始,我设置0然后有一个错误,为了修复错误我使用1作为第一个数字) 3.使用foo更改数据[行] [2],在同时你得到“新行”需要更改,新行需要更改为“新编号” 4.use foo 一次又一次
      • 修复另一个错误:def foo_whole(data): rows = [] num = 1 for subls in data: if subls[3] == "X": rows = [subls[0]] while True: data, rows, num = foo(data, rows, num) status = 'finished' for subls in data: if not subls[2]: status = 'unfinished' if status == 'finished': break for a in数据:a[2] = a[2] - 1 返回数据
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-26
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 2021-08-31
      相关资源
      最近更新 更多