簡體   English   中英

在每行之后迭代兩個列表切換方向的更多pythonic方式?

[英]More pythonic way to iterate through two lists switching directions after every line?

我正在編寫一些代碼,以一種奇怪的方式循環遍歷兩個列表。 我的目標是使用索引i遍歷所有列表a ,然后使用索引j遍歷b並來回交替。 即我想按順序遍歷對:

(0,0),...,(n,0),(0,1)...(0,m),(1,1)...,(n,1),(1,2)...,(1,m),(2,2),...,(n,m)

我當前的代碼是這樣寫的:

while i+j < len(a) + len(b) -2:
    #do stuff
    if direction_toggle:
        if i + 1 > len(a):
            direction_toggle = not direction_toggle
            i = j
        else:
            i += 1
    else:
        if j + 1 > len(b):
            direction_toggle = not direction_toggle
            j = i + 1
        else:
            j += 1

但是,我想更加pythonic,並遵循

平面優於嵌套。

我想寫一些看起來更像這樣的東西:

while i+j < len(a) + len(b) -2:
    #do stuff
    if direction_toggle:
        var, length = i, len(a)
    else:
        var, length = j, len(b)
    if var + 1 > length:
        direction_toggle = not direction_toggle
    else:
        var += 1

所以我的問題是:有沒有一種方法可以實現相同的目標但減少重復性,並去除一層嵌套? 從廣義上講,我的代碼非常簡單,但似乎無法避免以兩種不同的方式重復自己,我是否遺漏了什么,或者我的實現實際上是實現這一目標的最糟糕的方式?

PS我希望這不是重復的,我找不到解決這個主題的任何其他問題。

編輯清晰:我的具體要求是在點擊(i, j)之前處理(i, j-1)(i-1, j)(i-1, j-1) ) 。 滿足此要求的任何可能的迭代路徑都將起作用。 如果您感興趣,這是因為我正在嘗試實現 DTW 算法,其中矩陣中分配的每個值都取決於先前的相鄰值。

如果您通過 m 列網格將數字排列在 n 行中,您可以通過沿着第一列走,然后穿過第一行(從第 1 列開始),然后沿着第二列走(從行開始)來獲得解決方案1),然后穿過第二行(從第 2 列開始),然后向下穿過第三列(從第 2 行開始),等等。這只是實現了這一點。

def gen_tuples(n_rows, n_cols):
    row = col = 0
    while row <= n_rows and col <= n_cols:
        for i in range(row, n_rows + 1):
            yield (i, col)

        for j in range(col + 1, n_cols + 1):
            yield (row, j)

        row += 1
        col += 1


list(gen_tuples(5, 3))

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
 (0, 1), (0, 2), (0, 3),
 (1, 1), (2, 1), (3, 1), (4, 1), (5, 1),
 (1, 2), (1, 3),
 (2, 2), (3, 2), (4, 2), (5, 2),
 (2, 3),
 (3, 3), (4, 3), (5, 3)]

根據您的“為清晰而編輯”

我的具體要求是我在點擊(i,j)之前處理(i,j-1),(i-1,j)和(i-1,j-1)。

這可以通過

for i in range(n + 1):
    for j in range(m + 1):
         do_stuff()

如果這次我理解正確,如果這是一個 5 x 4 (n = 4, m = 3) 矩陣,您基本上需要以下順序:

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

你應該能夠遞歸地解決這個問題。

def stripes(r, c, r0=0, c0=0, flip=False):
    for row in range(r0, r + 1):
        yield (row, c0) if not flip else (c0, row)
    if r0 <= r:
        yield from stripes(c, r, r0=c0 + 1, c0=r0, flip=not flip)

接着:

>>> list(stripes(4, 3))
[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0),
 (0, 1), (0, 2), (0, 3),
 (1, 1), (2, 1), (3, 1), (4, 1),
 (1, 2), (1, 3),
 (2, 2), (3, 2), (4, 2),
 (2, 3),
 (3, 3), (4, 3)]

或針對您的特定用例:

cache = {}
for r, c in stripes(R, C):
    inputs = (r - 1, c), (r - 1, c - 1), (r, c - 1)
    a, b, c = (cache.get((x, y)) for x, y in inputs)
    cache[(r, c)] = do_stuff(a, b, c)

暫無
暫無

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

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