Как работает это выражение понимания вложенного списка?

#python #list #boolean

#python #Список #логическое

Вопрос:

У меня возникли некоторые проблемы с пониманием следующего понимания вложенного списка. Что делает первое ‘True’ в этом выражении? Как работает общее выражение?

 
#Use a nested list comprehension to find all of the numbers from 1-1000 that 
#are divisible by any single digit besides 1 (2-9)
# comprehension testing truth for divisibilty: [True for divisor in range(2,10) if number % divisor == 0]
results = [number for number in range(1,1001) if True in [True for divisor in range(2,10) if number % divisor == 0]]
#print(results)
  

Комментарии:

1. Обратите внимание, что True in [True for divisor in range(2,10) if number % divisor == 0] было бы более естественно записать как any(number % divisor == 0 for divisor in range(2,10)) .

Ответ №1:

Начните с изучения внутреннего понимания:

 [True for divisor in range(2,10) if number % divisor == 0]
  

На английском языке это говорит о том, что для всех divisor в range(2,10) , если divisor равномерно разделить number , то True они будут в списке. Другими словами, список будет состоять из ряда True значений, равных числу делителей от 2 до 9. Таким образом, если ничего от 2 до 9 не разделяется number , список будет пустым. Чтобы сделать это более понятным, абстрагируйте это в функции:

 def hasSingleDigitDivisorList(number):
    return [True for divisor in range(2,10) if number % divisor == 0]
  

(Обратите внимание, что эта абстракция предназначена исключительно для понимания выражения. Учитывая, насколько громоздким является название, возможно, не имеет смысла абстрагировать этот конкретный фрагмент кода в рабочей среде.)

Затем замените функцию в для понимания списка в исходном выражении:

 results = [number for number in range(1,1001) if True in hasSingleDigitDivisorList(number)]
  

Важным моментом является то, что список пуст, когда нет делителей, поскольку тест True in [...] завершится неудачей тогда и только тогда, когда список пуст. Другими словами, True in ... выражение проверяет, есть ли какие-либо делители от 2 до 9. Превратите это в функцию:

 def hasSingleDigitDivisor(number):
    return True in hasSingleDigitDivisorList(number)
  

( hasSingleDigitDivisor имеет больше смысла как функциональная единица, чем hasSingleDigitDivisorList , так что вы действительно можете использовать его в проекте.)

Затем замените эту новую функцию в общее выражение:

 results = [number for number in range(1,1001) if hasSingleDigitDivisor(number)]
  

На английском языке это выражение собирает все числа от 1 до 1000, если они имеют делитель из одной цифры (отличный от единицы), который соответствует комментарию над фрагментом:

 #... all of the numbers from 1-1000 that 
#are divisible by any single digit besides 1
  

Комментарии:

1. if True in [True for divisor in range(2,10) if number % divisor == 0] читается лучше как if any(number % divisor == 0 for divisor in range(2,10))