Цикл for-in Python, которому предшествует переменная

foo = [x for x in bar if x.occupants > 1]

После поиска в Интернете и поиска здесь не удалось понять, что это делает. Возможно, я не искал нужный материал, но вот он. Любой вход в развенчание этой стенографии приветствуется.

Ответ 1

Текущие ответы хороши, но не говорите о том, как они просто синтаксический сахар к некоторому шаблону, к которому мы так привыкли.

Начнем с примера, скажем, что у нас есть 10 чисел, и мы хотим подмножество тех, которые больше, чем, скажем, 5.

>>> numbers = [12, 34, 1, 4, 4, 67, 37, 9, 0, 81]

Для вышеупомянутой задачи нижеприведенные подходы полностью идентичны друг другу и переходят от большинства подробных к сжатым, читаемым и pythonic:

Подход 1

result = []
for index in range(len(numbers)):
    if numbers[index] > 5:
        result.append(numbers[index])
print result  #Prints [12, 34, 67, 37, 9, 81]

Подход 2 (Слегка чистые, замкнутые контуры)

result = []
for number in numbers:
    if number > 5:
        result.append(number)
print result  #Prints [12, 34, 67, 37, 9, 81]

Подход 3 (ввод списка)

result = [number for number in numbers if number > 5]

или более широко:

[function(number) for number in numbers if condition(number)]

где:

  • function(x) принимает x и преобразует его во что-то полезное (например, x*x)
  • если condition(x) возвращает любое значение False-y (False, None, пустая строка, пустой список и т.д.), то текущая итерация будет пропущена (подумайте continue). Если функция возвращает значение, отличное от False-y, то текущее значение переходит к окончательному результирующему массиву (и проходит этап преобразования выше).

Чтобы понять синтаксис несколько иначе, посмотрите раздел Бонус ниже.

Для получения дополнительной информации следуйте руководству, которое все другие ответы связали: List Comprehension


Bonus

(Немного непитонический, но поставив его ради полноты)

Приведенный выше пример можно записать в виде:

result = filter(lambda x: x > 5, numbers)

Общее выражение выше может быть записано как:

result = map(function, filter(condition, numbers)) #result is a list in Py2

Ответ 2

Это понимание списка

foo будет отфильтрованным списком bar, содержащим объекты с активными атрибутами > 1

bar может быть list, set, dict или любым другим итерируемым

Вот пример, чтобы уточнить

>>> class Bar(object):
...   def __init__(self, occupants):
...     self.occupants = occupants
... 
>>> bar=[Bar(0), Bar(1), Bar(2), Bar(3)]
>>> foo = [x for x in bar if x.occupants > 1]
>>> foo
[<__main__.Bar object at 0xb748516c>, <__main__.Bar object at 0xb748518c>]

Итак, foo имеет 2 bar объекта, но как мы можем проверить, какие из них? Давайте добавим метод __repr__ к bar, чтобы он был более информативным

>>> Bar.__repr__=lambda self:"Bar(occupants={0})".format(self.occupants)
>>> foo
[Bar(occupants=2), Bar(occupants=3)]

Ответ 3

Это возвращает список, содержащий все элементы в баре, в которых есть обитатели > 1.

Ответ 4

Как это должно работать, насколько я могу судить, проверяет, пуст ли пул (0) списка или состоит из singleton (1) через x.occupants, где x - определенный элемент в пределах и может иметь характеристику обитателей. Таким образом, foo вызывается, перемещается по списку и затем возвращает все элементы, которые передают условие проверки, которое является x.occant.

На языке, подобном Java, вы должны создать класс с именем "x" , где объекты "x" затем присваиваются массиву или тому подобному. X будет иметь поле, называемое "оккупантами", и каждый индекс будет проверяться с помощью метода x.occupants, который возвращает номер, присвоенный оккупанту. Если этот метод возвращается больше 1 (мы предполагаем, что int здесь, поскольку частичный пассажир был бы нечетным). Метод foo (вызывается в массиве или аналогичном в вопросе.) Затем возвращал массив или аналогичный, как определено в методе foo для этого контейнера или того, что у вас есть. Элементами возвращаемого массива будут объекты "x" в первом массиве, которые соответствуют критериям "Больше 1".

У Python есть встроенные методы посредством понимания списка, чтобы справиться с этим гораздо более сжатым и значительно упрощенным способом. Вместо того, чтобы реализовать два полных класса и несколько методов, я пишу одну строку кода.