Генераторы множеств

Самый простой генератор множеств состоит из выражения, объявления цикла и итерируемого объекта, которые заключены в фигурные скобки:

>>> {i**2 % 4 for i in range(10)}
{0, 1}

Если генератор множеств поместить внутрь функции frozenset() то в результате получится фиксированное множество:

>>> frozenset({i**2 % 4 for i in range(10)})
frozenset({0, 1})

В генераторе может располагаться несколько циклов и несколько итерируемых объектов

>>> r = set('ABCD')
>>>
>>> {i + j for i in r for j in r.difference({i})}
{'CB', 'DA', 'DB', 'BD', 'AC', 'BA', 'AD', 'CA', 'AB', 'DC', 'CD', 'BC'}

Фиксированные множества позволяют создавать множества множеств:

>>> r = set('ABCD')
>>>
>>> {frozenset({i + j for j in r.difference({i})}) for i in r}
{frozenset({'DB', 'DC', 'DA'}),
 frozenset({'BD', 'BC', 'BA'}),
 frozenset({'CD', 'CA', 'CB'}),
 frozenset({'AD', 'AC', 'AB'})}

Фиксированные множества так же могут быть ключами словарей:

>>> r = 'ABCD'
>>>
>>> {frozenset(r[:i]+r[i+1:]): r[i] for i in range(len(r))}
{frozenset({'C', 'D', 'B'}): 'A',
 frozenset({'A', 'C', 'D'}): 'B',
 frozenset({'A', 'D', 'B'}): 'C',
 frozenset({'A', 'C', 'B'}): 'D'}

Условие if и if... else...

Условие if указывается после объявления цикла и итерируемого объекта:

>>> r = ['ab_1', 'ac_2', 'bc_1', 'bc_2']
>>>
>>> {i for i in r if 'a' not in i}
{'bc_2', 'bc_1'}

Условное выражение if... else... указывается до объявления цикла:

>>> r = ['ab_1', 'ac_2', 'bc_1', 'bc_2']
>>>
>>> {'A' + i[1:] if i[0] == 'a' else 'B' + i[1:] for i in r}
{'Bc_2', 'Ac_2', 'Ab_1', 'Bc_1'}

Конструкции if и if... else... могут быть использованы одновременно:

>>> r = ['ab_1', 'ac_2', 'bc_1', 'bc_2']
>>>
>>> {'A' + i[1:] if i[0] == 'a' else 'B' + i[1:] for i in r if i[1] == 'c'}
{'Bc_2', 'Ac_2', 'Bc_1'}