การเปรียบเทียบรายการหลายรายการ Python
ฉันมีรหัสที่มีสามรายการจากนั้นจะตรวจสอบดัชนีของรายการที่สองเทียบกับดัชนีของรายการแรกตราบใดที่รายการแรกมีองค์ประกอบหกรายการ จากนั้นรหัสจะต่อท้ายรายการที่สามหากส่วนหนึ่งของสตริงตรงกับดัชนีของรายการแรก หากสตริงไม่ตรงกันก็จะต่อท้ายข้อความ ฉันหวังว่าจะพบวิธีการเขียนอัลกอริทึม Pythonic ที่ดีขึ้นและดีขึ้น นี่คือรหัสของฉัน:
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
รหัสนี้ใช้ได้กับสิ่งที่ฉันต้องการ แต่ฉันคิดว่ามันยาวเกินไป ความช่วยเหลือใด ๆ ในการทำให้รหัสนี้มากขึ้น Pythonic จะได้รับการชื่นชมอย่างมาก ขอบคุณล่วงหน้า.
คำตอบ
ทานของรหัสปัจจุบันของคุณเป็นเรื่องง่ายที่จะสรุป: มันเกินไปซับซ้อนยี้และทำให้หัวของฉันเจ็บ แต่อย่ารู้สึกแย่เพราะคุณอยู่ใน บริษัท ที่ยอดเยี่ยม ความพยายามครั้งแรกมักจะเป็นเช่นนั้นแม้กระทั่งกับคนที่ทำสิ่งนี้มาเป็นเวลานาน
อะไรที่ทำให้เข้าใจยากโดยเฉพาะ? ความซับซ้อนของอัลกอริทึม: ลูปและเงื่อนไขที่ซ้อนกันการแบ่งการจัดการดัชนีรายการและอื่น ๆ เมื่อใดก็ตามที่คุณรับรู้ถึงความซับซ้อนประเภทนั้นการพิจารณาว่าโครงสร้างข้อมูลที่มีประสิทธิภาพมากขึ้นจะทำให้สถานการณ์ง่ายขึ้นหรือไม่ (ฉันใช้ "โครงสร้างข้อมูล" ในความหมายที่กว้างมาก) ในการเขียนซ้ำที่นำเสนอด้านล่างนี้เราจะใช้การทำซ้ำแบบพิเศษที่ช่วยให้เรามองไปที่ค่าถัดไปโดยไม่ต้องใช้มันทุกครั้ง การเปลี่ยนแปลงอย่างหนึ่งทำให้การทำบัญชีง่ายขึ้นอย่างมากภายในลูปหลักและยังช่วยลดความซับซ้อนในการผนวกส่วนที่เหลือของค่าที่ขาดหายไปหลังจากที่เราออกจากลูป
# 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
เนื่องจากcontinueมักจะเกิดขึ้นที่ส่วนท้ายของลูปคุณสามารถย้อนกลับเงื่อนไขเหล่านี้เพื่อให้สั้นลงได้
if c >= len(L2):
c = 0
break
ตอนนี้คุณไม่ต้องการelseเพราะอย่างอื่นนอกจากเงื่อนไขการแบ่งจะcontinueโดยอัตโนมัติ
สูงกว่าที่คุณตั้งไว้cont = Falseคุณสามารถใช้breakแทนได้เท่าที่ฉันบอกได้ ซึ่งจะขจัดความจำเป็นcontทั้งหมดออกไปเพื่อให้คุณสามารถทำได้while True:
ฉันส่วนใหญ่จะตอบใน SO ดังนั้นคำตอบของฉันอาจไม่เป็นไปตาม PEP8 หรือหลักเกณฑ์อื่น ๆ แต่ฉันพยายามสร้างโค้ดของคุณที่ง่ายต่อการมองเห็นสิ่งที่เกิดขึ้นโดยไม่ต้องมีการหยุดพักดำเนินต่อไปและมีจำนวนบรรทัดน้อยลง
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