foo = [x for x in bar if x.occupants > 1]
Погугливши та шукаючи тут, не міг зрозуміти, що це робить. Можливо, я не шукав потрібні речі, але ось вони. Будь-який внесок у розвінчання цієї стенографії дуже вдячний.
foo = [x for x in bar if x.occupants > 1]
Погугливши та шукаючи тут, не міг зрозуміти, що це робить. Можливо, я не шукав потрібні речі, але ось вони. Будь-який внесок у розвінчання цієї стенографії дуже вдячний.
Відповіді:
Поточні відповіді хороші, але не варто говорити про те, як вони є просто синтаксичним цукром за якоюсь схемою, до якої ми так звикли.
Почнемо з прикладу, скажімо, у нас є 10 чисел, і ми хочемо підмножину тих, які більші, ніж, скажімо, 5.
>>> numbers = [12, 34, 1, 4, 4, 67, 37, 9, 0, 81]
Для вищезазначеного завдання наведені нижче підходи повністю ідентичні один одному і переходять від найбільш багатослівного до стислого, читабельного та пітонічного :
result = []
for index in range(len(numbers)):
if numbers[index] > 5:
result.append(numbers[index])
print result #Prints [12, 34, 67, 37, 9, 81]
result = []
for number in numbers:
if number > 5:
result.append(number)
print result #Prints [12, 34, 67, 37, 9, 81]
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
x*x
, це може бути просто там, а не square(x)
. Це робить його ще болючим тоді, коли я бачу, що вираз перетворився на лямбду, наприклад [x**2 for x in range(5)]
проти map(lambda x: x**2, range(5))
.
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)]
Наскільки я можу зрозуміти, це повинно працювати, це перевірка на те, чи порожній список "bar" (0), чи складається з одиничного елемента (1) через x.occupants, де x - визначений елемент у рядку списку, може мати характеристику мешканців. Тож foo викликається, рухається по списку, а потім повертає всі елементи, які проходять умову перевірки x.occupant.
У такій мові, як Java, ви створюєте клас під назвою "x", де об'єкти "x" потім призначаються масиву або тому подібному. X мав би поле, яке називається "мешканці", і кожен індекс перевірявся б методом x.occupants, який повертав би номер, присвоєний мешканцю. Якби цей метод повернув більше 1 (ми припускаємо, що int тут, оскільки частковий мешканець буде непарним.), Метод foo (викликаний для масиву або подібного, про який йде мова.) Тоді поверне масив або подібний, як визначено в методі foo для цього масиву контейнерів або що у вас є. Елементами поверненого масиву будуть об'єкти 'x' у першій річці масиву, які відповідають критеріям "Більше 1".
Python має вбудовані методи за допомогою розуміння списку, щоб вирішити це набагато коротше і значно спрощеніше. Замість реалізації двох повних класів та декількох методів я пишу цей рядок коду.
Це повертає список, який містить усі елементи в панелі, які мають мешканців> 1.
Оскільки на програмову частину запитання відповідають інші, приємно знати її відношення до математики ( теорії множин ). Насправді це реалізація Python нотації конструктора наборів :
Визначення набору за аксіомою специфікації :
B = {x є A: S (x)}
Англійський переклад: B - це набір, де його члени вибираються з A , тому B - це підмножина A (B ⊂ A), де характеристика (и), зазначена функцією S, виконує:
S(x) == True
Визначення B за допомогою розуміння списку:
B = [x для x в A, якщо S (x)]
Отже, щоб побудувати B з розумінням списку , члени B (позначені x ) вибираються із набору A де S(x) == True
(умова включення).
Примітка: Функція, S
яка повертає логічне значення, називається предикатом .
python "* for * in * if"
і це був перший хіт secnetix.de/olli/Python/list_comprehension.hawk