2017-07-19 4 views
4

Betrachten wir zwei Listen, zum Beispiel:Join zwei Listen Offset

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 
M = [1, 2, 3, 4, 5, 6, 7, 8] 

Lassen Sie uns sagen, dass wir ein Paar von Elementen gegeben sind, die übereinstimmen müssen - zum Beispiel (d, 6) ("Offset zip"?). Ist es möglich, die Listen an diesen Elementen auszurichten und dann den Listen beizutreten, wo immer noch Elemente in beiden Listen sind - eine Art Kreuzung zwischen einer Zip- und einer inneren Verknüpfung?

Dies ist wahrscheinlich am besten durch ein Beispiel veranschaulicht. wie oben unter Verwendung L und M:

  • (d, 6) würde [(a, 3), (b, 4), (c, 5), (d, 6), (e, 7), (f, 8)] führen
  • (h, 2) zu [(g, 1), (h, 2)]
  • (a, 8)

    Mein Kontext [(a, 8)]

führen würde führen würde: Ich m versuche gerade g ein neuronales Netzwerk aufzubauen, das durch das Lesen der Schachnotation lernen kann, Schach zu spielen. Diese Frage hat damit zu tun, die Diagonalen auf der Tafel zu überprüfen, um die Positionen der Teile zu aktualisieren. Wenn zum Beispiel ein weißer Läufer gerade nach b7 gezogen ist (ein Rechteck von der unteren rechten Ecke des Bretts), muss er von einem Quadrat auf der langen Diagonale h1-a8 oder von einem Feld auf der a6-c8 gekommen sein kurze Diagonale.

Also in meinem Fall, L und M sind die gleiche Länge, da sie den Rängen und Dateien auf einem 8-by-8-Schachbrett entsprechen. Aber im Allgemeinen nehme ich an, dass die Listen unterschiedlich lang sein könnten.

Antwort

1

Sie könnten etwas entlang der Linien von

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 
M = [1, 2, 3, 4, 5, 6, 7, 8] 
m = L.index('h') 
n = M.index(2) 
if m > n: 
    m, n = (m - n), 0 
else: 
    m, n = 0, (n - m) 
print(list(zip(L[m:], M[n:]))) 

PS tun Sie wahrscheinlich den m, n Indizierungs kompakter machen könnten, aber es ist klarer, was mit dieser Struktur geschieht angenommen hat.

+0

Das macht es sehr deutlich, was vor sich geht - danke! – owenjonesuob

1

Hier ist ein Ansatz, der itertools.dropwhile in beiden Listen zuerst in Vorwärtsreihenfolge verwendet, dann umgekehrte Aufnahme von Elementen vor und nach den Verknüpfungselementen aus beiden Listen.

Die beiden resultierenden Iterables sind dann gekettet, aber nicht nach dem Join Punkte von einem der Iterables fallen itertools.islice mit:

from itertools import dropwhile, islice, chain 

def func(x, y, lst1, lst2): 
    f1 = lambda i: i!=x 
    f2 = lambda i: i!=y 
    r = zip(dropwhile(f1, lst1), dropwhile(f2, lst2)) 
    q = reversed(zip(dropwhile(f1, reversed(lst1)), dropwhile(f2, reversed(lst2)))) 
    return list(chain(q, islice(r, 1, None))) 

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 
M = [1, 2, 3, 4, 5, 6, 7, 8] 

print(func('d', 6, L, M)) 
# [('a', 3), ('b', 4), ('c', 5), ('d', 6), ('e', 7), ('f', 8)] 

print(func('h', 2, L, M)) 
# [('g', 1), ('h', 2)] 

print(func('a', 8, L, M)) 
# [('a', 8)] 

machen zwei Durchgänge auf beiden Listen nicht sehr effizient sein, aber die Lazy Evaluation (s) könnte mit großen Listen umgehen.

+0

In meinem Fall mit zwei kurzen Listen ist das wahrscheinlich etwas extravagant, aber ich schätze die mögliche Skalierbarkeit Ihrer Antwort und werde darauf zurückkommen, sollte ich in Zukunft größere Listen verwenden - vielen Dank! – owenjonesuob