Как уже отмечали другие, len("CCC-A-H") == 7
и python используют оценку короткого замыкания в логических операциях.Конечным результатом является то, что:
(len("CCC-A-H") == 5 or len("CCC-A-H") == 7 or "CCC-A-H"[6] != "H")
вернет true, поскольку len("CCC-A-H") == 7
оценивается как true до "CCC-A-H"[6] != "H"
.
Это может быть легче увидеть с помощью filter(...)
функция вместо понимания списка:
list1 = ["CCC-C", "CCC-P", "CCC-A-P", "CCC-A-H", "CCC-J", "CCC-S-X"]
def len57notHWrong(item):
return len(item) == 5 or len(item) == 7 or item[6] != "H"
print "Wrong : ", filter(len57notHWrong, list1)
Это простой прямой перевод понимания списка, который вы использовали при использовании функции filter(...)
.
Если бы мы переписали это, используя if ... elif ... else
конструкции, это будет выглядеть примерно так:
def len57notHWrongExpanded(item):
if len(item) == 5: # first check if length is 5
return True
elif len(item) == 7: # now check if length is 7
return True # it's 7? Short-circuit, return True
elif item[6] != "H": # This will never get seen (on this particular dataset)
return True
return False
print "Wrong (Expanded): ", filter(len57notHWrongExpanded, list1)
Правильное выражение будет выглядеть следующим образом:
def len57notH(item):
return len(item) == 5 or (len(item) == 7 and item[6] != "H")
print "Correct : ", filter(len57notH, list1)
Expanded:
def len57notHExpanded(item):
if len(item) == 5:
return True
elif len(item) == 7:
if item[6] != "H":
return True
return False
print "Correct (Expand): ", filter(len57notHExpanded, list1)
Это будет делатьпонимание списка выглядит так:
new_list = [i for i in list1 if (len(i) == 5 or (len(i) == 7 and i[6] != "H"))]
Причина, по которой ваш код не вызывает ошибку IndexError, заключается в том, что все ваши элементы данных имеют длину 5 или 7 элементов.Это приводит к короткому замыканию кода перед попаданием в выражение i[6] != "H"
.Если вы попробуете этот код в списке, который содержит элементы данных, которые не имеют длину 5 или 7 и длину менее 7 элементов, то возникает IndexError:
list2 = ["CCC-C", "CCC-P", "CCC", "CCC-A-P", "CCC-A-H", "CCC-J", "CCC-S-X"]
new_list = [i for i in list2 if (len(i) == 5 or len(i) == 7 or i[6] != "H")]
Traceback (most recent call last):
File "C:/Users/xxxxxxxx/Desktop/t.py", line 44, in <module>
new_list = [i for i in list2 if (len(i) == 5 or len(i) == 7 or i[6] != "H")]
IndexError: string index out of range
Извините, это немного длинный ответ...