Çoklu liste karşılaştırması Python
Üç listeli bir kodum var ve daha sonra, ilk liste altı öğeye sahip olduğu sürece, ikinci listenin dizinini birinci listenin diziniyle karşılaştırarak kontrol ediyor. Bir dizenin bir bölümü ilk listenin diziniyle eşleşirse, kod üçüncü listeye eklenir. Dize eşleşmezse, bir mesaj ekleyecektir. Algoritmamı yazmanın daha iyi, daha Pythonic yolunu bulmayı umuyorum. İşte kodum:
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
Bu kod benim yapmasını istediğim şey için çalışıyor ama bence çok uzun. Bu kodu daha Pythonic yapmak için herhangi bir yardım çok takdir edilecektir. Şimdiden teşekkürler.
Yanıtlar
Mevcut kodunuzla ilgili incelememin özetlenmesi kolaydır: Çok karmaşık ve başımı ağrıttı . Ama kendinizi kötü hissetmeyin çünkü harika bir şirketsiniz. İlk girişimler genellikle böyledir - bunu uzun süredir yapan insanlar için bile.
Özellikle anlamayı zorlaştıran nedir? Algoritmik karmaşıklık: iç içe geçmiş döngüler ve koşul ifadeleri, kesmeler, liste dizinlerini yönetme vb. Bu tür bir karmaşıklığı algıladığınızda, genellikle daha güçlü bir veri yapısının durumu basitleştirip basitleştirmeyeceğini düşünmek yardımcı olur ("veri yapısını" çok geniş anlamda kullanıyorum). Aşağıda sunulan yeniden yazımda, her seferinde onu gerçekten tüketmeden bir sonraki değere göz atmamızı sağlayan özel bir yinelenebilirlik kullanacağız. Bu tek değişiklik, ana döngü içindeki defter tutmayı büyük ölçüde basitleştirir ve ayrıca döngüden çıktıktan sonra gerekli kalan eksik değerleri nasıl ekleyeceğimizi basitleştirir.
# 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
Yana continuehep bir döngü sonunda olur, bunu kısaltmak için, bu koşulları tersine çevirebilir.
if c >= len(L2):
c = 0
break
elsekırılma durumu dışında herhangi bir şey continueotomatik olarak gerçekleşeceği için artık ihtiyacınız yok .
Ayarladığınız yerden daha yükseğe cont = False, breaksöyleyebileceğim kadarıyla onun yerine kullanabilirsiniz . Bu, ihtiyacınızı conttamamen ortadan kaldırır, böylece sadece yapabilirsinizwhile True:
Çoğunlukla SO'ya cevap veriyorum, bu yüzden cevabım PEP8'i veya diğer yönergeleri takip etmiyor olabilir, ancak kodunuzun, ifler, kesintiler, devam eden ve daha küçük bir satır sayısına sahip, neler olup bittiğini görmek için daha kolay bir versiyonunu yapmaya çalıştım:
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