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

2024-05-23 13:36:02 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题是this问题的扩展。你知道吗

我用列表列表来表示一个二维数组,L,比如说:

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

对于一个给定的子列表,比如说[9, 99],我想用这个sublist替换“2-D”列表中的一个特定子列表,使用如下直观的方法:

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 ^{}Transpose 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),用于垂直替换(这是本问题的重点)。你知道吗


Tags: to方法informatwhich列表lennot
1条回答
网友
1楼 · 发布于 2024-05-23 13:36:02

循环方法:

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]]

转置/切片/转置方法:

我把“禁止转置”的说法看过头了。这是使用转置,改变,转置方法与切片,这是Q不想要的。这是这个问题标题的答案,所以我决定把它留给以后的人们去搜索,然后在这个问题上绊倒:

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

对于4x4列表,使用ZIPPing(transpose/slice/transpose)的方法大约需要60%的时间。你知道吗


更大的列表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的评论

相关问题 更多 >