다중 목록 비교 Python
세 개의 목록이있는 코드가 있는데 첫 번째 목록에 여섯 개의 요소가있는 한 두 번째 목록의 색인과 첫 번째 목록의 색인을 확인합니다. 문자열의 일부가 첫 번째 목록의 색인에서 일치하면 코드가 세 번째 목록에 추가됩니다. 문자열이 일치하지 않으면 메시지를 추가합니다. 알고리즘을 작성하는 더 나은 Python 방식을 찾고 싶습니다. 내 코드는 다음과 같습니다.
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으로 만드는 데 도움을 주시면 대단히 감사하겠습니다. 미리 감사드립니다.
답변
현재 코드에 대한 리뷰는 요약하기 쉽습니다. 너무 복잡하고 머리가 아파요 . 그러나 당신은 훌륭한 회사에 있기 때문에 기분 나빠하지 마십시오. 첫 번째 시도는 종종 그와 같습니다. 심지어 오랫동안이 일을해온 사람들에게도 그렇습니다.
구체적으로 이해하기 어렵게 만드는 것은 무엇입니까? 알고리즘 복잡성 : 중첩 된 루프 및 조건, 중단, 목록 색인 관리 등. 이러한 유형의 복잡성을 인식 할 때마다 더 강력한 데이터 구조가 상황을 단순화하는지 여부를 고려하는 것이 종종 도움이됩니다 (저는 매우 넓은 의미에서 "데이터 구조"를 사용합니다). 아래 제공된 재 작성에서 우리는 매번 실제로 소비하지 않고 다음 값을 엿볼 수있는 특별한 iterable을 사용할 것입니다. 그 한 가지 변경은 메인 루프 내부의 부기를 대폭 단순화하고 루프를 종료 한 후 필요한 나머지 누락 된 값을 추가하는 방법도 단순화합니다.
# 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:
나는 주로 대답하고 있으므로 내 대답은 PEP8 또는 다른 지침을 따르지 않을 수 있지만 ifs, breaks, continue 및 더 작은 줄 수없이 무슨 일이 일어나고 있는지 더 쉽게 볼 수있는 코드 버전을 만들려고했습니다.
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