Mehrfachlistenvergleich Python
Ich habe einen Code mit drei Listen, der dann den Index der zweiten Liste mit dem Index der ersten vergleicht, solange die erste Liste sechs Elemente enthält. Der Code wird dann an die dritte Liste angehängt, wenn ein Teil einer Zeichenfolge mit dem Index der ersten Liste übereinstimmt. Wenn die Zeichenfolge nicht übereinstimmt, wird eine Nachricht angehängt. Ich hoffe, eine bessere, pythonischere Art zu finden, meinen Algorithmus zu schreiben. Hier ist mein Code:
L1 = ["first = 1st","second = 2nd","third = 3rd","fourth = 4th","sixth = 6th",
"first = A","second = B","third = C","fifth = E","sixth = F",
"second = W","third = X","fourth = Y","fifth = Z","sixth = AA","first = BB"]
L2 = ["first","second","third","fourth","fifth","sixth"]
L3 = []
#Used in case a list has less than six elements
if len(L1) % 6 != 0:
L1.append("Missing_Data")
c = 0
for i in L1:
cont = True
while cont:
if L2[c] in i:
L3.append(i.split("= ")[-1])
c += 1
if c < len(L2):
cont = False
else:
c = 0
cont = False
else:
L3.append("Missing_Data")
c += 1
if c < len(L2):
continue
else:
c = 0
break
Dieser Code funktioniert für das, was ich möchte, aber ich denke, er ist zu lang. Jede Hilfe, um diesen Code pythonischer zu gestalten, wäre sehr dankbar. Danke im Voraus.
Antworten
Meine Überprüfung Ihres aktuellen Codes lässt sich leicht zusammenfassen: Es ist verdammt kompliziert und macht mir Kopfschmerzen . Aber fühlen Sie sich nicht schlecht, denn Sie sind in guter Gesellschaft. Erste Versuche sind oft so - auch für Menschen, die dies schon lange tun.
Was macht es konkret schwer zu verstehen? Algorithmische Komplexität: verschachtelte Schleifen und Bedingungen, Unterbrechungen, Verwalten von Listenindizes usw. Wann immer Sie diese Art von Komplexität wahrnehmen, ist es oft hilfreich zu überlegen, ob eine leistungsfähigere Datenstruktur die Situation vereinfachen würde (ich verwende "Datenstruktur" im weitesten Sinne). In der unten angebotenen Umschreibung verwenden wir eine spezielle Iterable, mit der wir einen Blick auf den nächsten Wert werfen können, ohne ihn jedes Mal tatsächlich zu verbrauchen. Diese eine Änderung vereinfacht die Buchhaltung innerhalb der Hauptschleife drastisch und vereinfacht auch das Anhängen des erforderlichen Rests fehlender Werte nach dem Verlassen der Schleife.
# This is a third party library that is worth knowing about.
from more_itertools import peekable
# Your data, aligned so we can see what is going on.
# When you ask a question, it's a good idea to help your helpers.
xs = [
'first = 1st', 'second = 2nd', 'third = 3rd', 'fourth = 4th', 'sixth = 6th',
'first = A', 'second = B', 'third = C', 'fifth = E', 'sixth = F',
'second = W', 'third = X', 'fourth = Y', 'fifth = Z', 'sixth = AA',
'first = BB',
]
ys = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']
# Python has a builtin concept for missing data. Use it if you can.
# If you cannot, define a constant.
MISSING = None
# The results we want.
# When you ask a question, it's a good idea to provide this.
EXPECTED = [
'1st', '2nd', '3rd', '4th', MISSING, '6th',
'A', 'B', 'C', MISSING, 'E', 'F',
MISSING, 'W', 'X', 'Y', 'Z', 'AA',
'BB', MISSING, MISSING, MISSING, MISSING, MISSING
]
# We will use a peekable iterable for both the Xs and the Ys.
xit = peekable(xs)
yit = None
results = []
# Process all Xs to build the results.
# A Y is consumed each time, and we get a fresh Ys iterable as needed.
# We consume an X only when current X and Y agree.
while xit:
yit = yit or peekable(ys)
x = xit.peek()
y = next(yit)
val = next(xit).split('= ')[-1] if y in x else MISSING
results.append(val)
# The results should always contain a full cycle of Ys.
results.extend(MISSING for _ in yit)
# Check.
print(results == EXPECTED)
if c < len(L2):
continue
else:
c = 0
break
Da dies continueimmer am Ende einer Schleife geschieht, können Sie diese Bedingungen umkehren, um sie kürzer zu machen.
if c >= len(L2):
c = 0
break
Jetzt brauchen Sie elsenichts mehr als die Unterbrechungsbedingung continueautomatisch.
Weiter oben, wo Sie eingestellt haben cont = False, können Sie breakstattdessen verwenden, soweit ich das beurteilen kann. Damit entfällt die Notwendigkeit für continsgesamt, so dass Sie einfach tun könnenwhile True:
Ich antworte hauptsächlich auf SO, daher folgt meine Antwort möglicherweise nicht PEP8 oder anderen Richtlinien, aber ich habe versucht, eine Version Ihres Codes zu erstellen, die einfacher zu erkennen ist, was vor sich geht, ohne Wenn, Unterbrechungen, Fortfahren und mit einer geringeren Zeilenanzahl:
length = len(L2)
missing = 'Missing_Data'
index = -1
for item in L1:
key,value = item.split(' = ')
current = L2.index(key)
no_missing = (current-index)%length-1 # get number of missing elements
L3 += [missing] * no_missing # append this many of the missing value
L3.append(value) # append current value
index = current
L3 += [missing] * (length-index-1) # fill rest of list with missing elements