Цикл Python for-in, которому предшествует переменная - PullRequest
67 голосов
/ 25 июня 2011
foo = [x for x in bar if x.occupants > 1]

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

Ответы [ 4 ]

60 голосов
/ 17 июня 2016

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

Давайте начнем с примера, скажем, мыиметь 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, текущее значение попадает в окончательный результирующий массив (и проходит вышеописанный шаг преобразования).

Чтобы понять синтаксис немного по-другомусм. раздел «Бонусы» ниже.

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


Бонус

(Слегка непитонично, но для полноты изложения)

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

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

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

result = map(function, filter(condition, numbers)) #result is a list in Py2
26 голосов
/ 25 июня 2011

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

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)]
0 голосов
/ 25 июня 2011

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

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

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

0 голосов
/ 25 июня 2011

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

...