簡體   English   中英

在列表列表中替換垂直子列表

[英]Replacing a vertical sublist in a list of lists

該問題是對該問題的擴展。

我使用列表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] 如果必須使用此切片系統,則可以轉置L列表的 轉置 列表 ),然后使用此切片方法,然后將其轉回。 但是,即使是為了簡單起見,這也不是很有效。

復制 L[0:2][0] 並獲得此輸出 的有效方法是 什么?

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

注意:假設len(sublist) <= len(L) ,以進行垂直替換(這是此問題的重點)。

循環方法:

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

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的評論

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM