

forループ中での3次元配列への数字の挿入と条件分岐で困っています。

li1[i][j][k]の数字とli2[l][1]が一致した際に、li2[l][0]とli2[l][2]を、li1の中のli2[l][1]の前後に挿入したいと考えています。

[code]

    li1=[[[0, 1, 10], [0, 2, 10]], 
     [[0, 1, 3, 5, 10], [0, 1, 3, 6, 10], [0, 1, 4, 5, 10], [0, 1, 4, 6, 10], [0, 2, 3, 5, 10], [0, 2, 3, 6, 10], [0, 2, 4, 5, 10], [0, 2, 4, 6, 10]]]
    
    li2=[[7,1,8], [9,2,11], [12,3,13], [14,4,15], [16,5,17], [18,6,19]]
    
    for i in range(len(li1)):
        for j in range(len(li1[i])):
            for k in range(1,len(li1[i][j])-1):
                for l in range(len(li2)):#
                    if li1[i][j][k]==li2[l][1]:
                        li1[i][j].insert(k,li2[l][0])
                        li1[i][j].insert(k+2,li2[l][2])
    
    
    print(li1)
    
    
    >>> 
    [[[0, 7, 1, 8, 10], [0, 9, 2, 11, 10]], 
     [[0, 7, 7, 7, 1, 8, 8, 8, 3, 5, 10], [0, 7, 7, 7, 1, 8, 8, 8, 3, 6, 10], [0, 7, 7, 7, 1, 8, 8, 8, 4, 5, 10], [0, 7, 7, 7, 1, 8, 8, 8, 4, 6, 10], [0, 9, 9, 9, 2, 11, 11, 11, 3, 5, 10], [0, 9, 9, 9, 2, 11, 11, 11, 3, 6, 10], [0, 9, 9, 9, 2, 11, 11, 11, 4, 5, 10], [0, 9, 9, 9, 2, 11, 11, 11, 4, 6, 10]]]
    
[/code]

最終的な結果として3次元配列のresultを導出したいと考えています。  
上の結果ですと7や8などが3回連続してしまっていたり、下のresultと全く異なった結果となってしまっている状況です。

[code]

    result=[[[0,7,1,8,10],[0,9,2,11,10]],
        [[0,7,1,8,12,3,13,18,6,19,10],[0,7,1,8,12,3,13,18,6,19,10],[0,7,1,8,14,4,15,16,5,17,10], [0,7,1,8,14,4,15,18,6,19,10], [0, 2, 3, 5,10], [0,9,2,11,12,3,13,18,6,19,10], [0,9,2,11,14,4,15,16,5,17,10], [0,9,2,11,14,4,15,18,6,19,10]]]
    
[/code]

別の書き方でも全く問題ないです。よろしくお願いします。


CC BY-SA 3.0
2015-11-20T09:37:29.763
19082
2015-11-20T13:05:26.370
2015-11-20T09:44:28.513
13347
13347
question
python
forループ中での3次元配列への数字の挿入と条件分岐について


`insert()` によって `li1[i][j]` の長さが変化してしまいますので、`k`
をインデックスとして使うとおかしな事になってしまいます。別の変数(`m`)をインデックスとして使う様に変更します。

[code]

    for i in range(len(li1)):
      for j in range(len(li1[i])):
        m = 0
        for k in range(1,len(li1[i][j])-1):
          m += 1 
          for l in range(len(li2)):
            if li1[i][j][m]==li2[l][1]:
              li1[i][j].insert(m,li2[l][0])
              li1[i][j].insert(m+2,li2[l][2])
              m += 2
    
[/code]


CC BY-SA 3.0
2015-11-20T11:49:21.733
19089
2015-11-20T11:49:21.733
19082
answer


ループの途中でループ対象のリストをいじれば、インデックスが変わりますから、どんどん面倒になります。  
リストを組み立てる場合は、既存のリストを変更するのでは無く、新しいリストを作ると楽です。

まずは`li1`を新しいリストにコピーするコードを考えてみて下さい。  
そして、`li1`の要素を足していく箇所に、条件により処理を加える、という流れです。

以下は質問のコードを出来るだけそのままで、新規リストを作る方法に変更した物です。  
処理を加える部分を別の関数に切り出すですとか、いろいろと整理する方法は考えられますが。

出力は質問で示されている`result`とは一致しないですね。  
どちらかに間違いがあるのでしょう。

[code]

    #!/usr/bin/python3
    
    li1=[[[0, 1, 10], [0, 2, 10]], 
     [[0, 1, 3, 5, 10], [0, 1, 3, 6, 10], [0, 1, 4, 5, 10], [0, 1, 4, 6, 10], [0, 2, 3, 5, 10], [0, 2, 3, 6, 10], [0, 2, 4, 5, 10], [0, 2, 4, 6, 10]]]
    
    li2=[[7,1,8], [9,2,11], [12,3,13], [14,4,15], [16,5,17], [18,6,19]]
    
    result = []
    
    for i in range(len(li1)):
        result.append([])
        for j in range(len(li1[i])):
            result[-1].append([])
            for k in range(len(li1[i][j])):
                if k == 0 or k == len(li1[i][j]) - 1:
                    result[-1][-1].append(li1[i][j][k])
                else:
                    add = [ li1[i][j][k] ] 
                    for l in range(len(li2)):
                        if li1[i][j][k] == li2[l][1]:
                            add = li2[l]
                            break
                    result[-1][-1].extend(add)
    
    
    from pprint import pprint
    pprint(result)
    
[/code]

結果

[code]

    [[[0, 7, 1, 8, 10], [0, 9, 2, 11, 10]],
     [[0, 7, 1, 8, 12, 3, 13, 16, 5, 17, 10],
      [0, 7, 1, 8, 12, 3, 13, 18, 6, 19, 10],
      [0, 7, 1, 8, 14, 4, 15, 16, 5, 17, 10],
      [0, 7, 1, 8, 14, 4, 15, 18, 6, 19, 10],
      [0, 9, 2, 11, 12, 3, 13, 16, 5, 17, 10],
      [0, 9, 2, 11, 12, 3, 13, 18, 6, 19, 10],
      [0, 9, 2, 11, 14, 4, 15, 16, 5, 17, 10],
      [0, 9, 2, 11, 14, 4, 15, 18, 6, 19, 10]]]
    
[/code]


CC BY-SA 3.0
2015-11-20T11:53:27.043
19090
2015-11-20T11:53:27.043
3054
19082
answer