替换列表列表中的垂直子列表

时间:2018-02-09 18:03:44

标签: python list matrix replace

此问题是对this问题的延伸。

我使用列表列表L表示二维数组,说:

[ [1, 2, 3, 4],
  [1, 2, 3, 4],
  [1, 2, 3, 4],
  [1, 2, 3, 4] ]

对于给定的子列表,例如[9, 99],我想替换" 2-D"中的特定子列表。这个sublist使用直观的内容列出:

L[1][0:2] = sublist

# which updates `L` to:

[ [1, 2, 3, 4],
  [1, 9, 99, 4],
  [1, 2, 3, 4],
  [1, 2, 3, 4] ] # not in this format, but written like this for clarity

这适用于水平替换,但不适用于垂直替换,因为我们无法切片来分隔这样的列表:L[0:2][0]。如果我 使用此切片系统,我可以transpose LTranspose list of lists),然后使用此切片方法,然后将其转置回来。但即使为了简单起见,这也没有效率。

什么是有效的复制方式 L[0:2][0] 并获得此输出?

[ [1, 2, 3, 4],
  [1, 9, 3, 4],
  [1, 99, 3, 4],
  [1, 2, 3, 4] ]

注意:假设len(sublist) <= len(L),用于垂直替换(这是此问题的重点)。

1 个答案:

答案 0 :(得分:2)

循环方法:

def replaceVert(al : list, repl:list, oIdx:int, iIdx:int):
    for pos in range(len(repl)):
        al[oIdx+pos][iIdx] =  repl[pos]

a = [ [1, 2, 3, 4],
      [5, 6, 7, 8],
      [9, 10, 11, 12],
      [13, 14, 15, 16] ]

print(a)   # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

replaceVert(a,['ä','ü'],2,2)  # this is a one liner ;)

print(a)   # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 'ä', 12], [13, 14, 'ü', 16]]

转置/切片/转置方法:

我过度提及&#34;没有转置&#34;。这是使用转置,更改,转置方法,切片,这是Q 不需要的。它这个问题的标题的答案,所以我决定留下来让未来的人搜索SO并偶然发现这个问题:

a = [ [1, 2, 3, 4],
      [5, 6, 7, 8],
      [9, 10, 11, 12],
      [13, 14, 15, 16] ] 

b = list(map(list,zip(*a)))  # will make [ [1,5,9,13], ... ,[4,8,12,16]]
b[1][0:2]=['a','b']          # replaces what you want here (using a and b for clarity)
c = list(map(list,zip(*b)))  # inverts b back to a's form

print(a)
print(b)
print(c) 

输出:

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]     # a
[[1, 5, 9, 13], ['a', 'b', 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]] # b replaced 
[[1, 'a', 3, 4], [5, 'b', 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] # c

时间4x4列表,2替换

setuptxt = """
def replaceVert(al : list, repl:list, oIdx:int, iIdx:int):
    for pos in range(len(repl)):
        al[oIdx+pos][iIdx] =  repl[pos]

a = [ [1, 2, 3, 4],
      [5, 6, 7, 8],
      [9, 10, 11, 12],
      [13, 14, 15, 16] ]
"""
zipp = """b = list(map(list,zip(*a)))  
b[1][0:2]=['a','b']           
c = list(map(list,zip(*b)))
"""

import timeit

print(timeit.timeit("replaceVert(a,['ä','ü'],2,2)",setup = setuptxt))
print(timeit.timeit(stmt=zipp, setup=setuptxt))

输出:

looping: 12.450226907037592
zipping: 7.50479947070815

ZIPPing(转置/切片/转置)的方法大约需要60%的时间用于4x4列表。

更大的名单1000x1000和~70个元素已被替换:

setuptxt = """
def replaceVert(al : list, repl:list, oIdx:int, iIdx:int):
    for pos in range(len(repl)):
        al[oIdx+pos][iIdx] =  repl[pos]

a = [ [kk for kk in range(1+pp,1000+pp)] for pp in range(1,1000)] 
repl = [chr(mm) for mm in range(32,100)]
"""

import timeit


print(timeit.timeit("replaceVert(a,repl,20,5)",number=500, setup = setuptxt))

zipp = """b = list(map(list,zip(*a)))  
b[20][5:5+len(repl)]=repl           
c = list(map(list,zip(*b)))
"""

print(timeit.timeit(stmt=zipp, setup=setuptxt,number=500))

输出:

looping: 0.07702917579216137
zipping: 69.4807168493871 

循环胜利。感谢@Sphinx的评论