Começo pela curiosidade. E digo curiosidade, porque penso que é a primeira linguagem de programação onde vejo esta construção. Há outras linguagens pelas quais nunca incursei, como o Ruby, ou incursei pouco, como o Perl, que talvez permitam este tipo de construções, mas nunca vi. A sintaxe seguinte permite criar uma lista de valores que é um subconjunto de uma progressão aritmética.
>>> a = 42 >>> b = list(a + i for i in range(10)) >>> b [42, 43, 44, 45, 46, 47, 48, 49, 50, 51]
Ou ainda:
>>> list(map(lambda x: 2*x, (a + i for i in range(10)))) [84, 86, 88, 90, 92, 94, 96, 98, 100, 102]
Passemos às expressões. Nas expressões aritméticas, as conversões são feitas sempre para cima, antes de operar. “Para cima” significa, que entre dois operandos de tipos diferentes, a conversão é feita para o tipo “maior”, sendo a sequência crescente a seguinte: int, long, float, complex. Os booleanos são inteiros. A unidade imaginária é o j.
>>> 5+True 6 >>> True + (2.5+3j) (3.5+3j)
Segundo o manual do Python, as expressões podem ser as seguintes, sendo algumas delas apresentadas em sintaxe BNF:
- Conversões aritméticas
- Átomos
- Identificadores
- Literais
- Lista entre parêntesis
- Listas
- Conjuntos e dicionários
- Expressões geradoras
- Conversões de strings
- Expressões “yield”
- Operações primárias
primary ::= atom | attributeref | subscription | slicing | call
- Referências a atributos
- Indexação
- Cortes
- Chamadas
- Potência
power ::= primary ["**" u_expr]
- Operações unárias
u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr
- Operações aritméticas
m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr | m_expr "%" u_expr a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr
- Operações de deslocamento
shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr
- Operações bit a bit
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
- Comparações
comparison ::= or_expr ( comp_operator or_expr )* comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!=" | "is" ["not"] | ["not"] "in"
- Operações booleanas
or_test ::= and_test | or_test "or" and_test and_test ::= not_test | and_test "and" not_test not_test ::= comparison | "not" not_test
- Expressões condicionais
conditional_expression ::= or_test ["if" or_test "else" expression] expression ::= conditional_expression | lambda_expr
- Lambdas
lambda_expr ::= "lambda" [parameter_list]: expression
- Expressões com listas
expression_list ::= expression ( "," expression )* [","]
A tabela de precedências dos operadores, do mais fraco para o mais forte, é a seguinte:
Operator | Description |
---|---|
lambda | Lambda expression |
if – else | Conditional expression |
or | Boolean OR |
and | Boolean AND |
not x | Boolean NOT |
in, not in, is, is not, <, <=, >, >=, <>, !=, == |
Comparisons, including membership tests and identity tests |
| | Bitwise OR |
^ | Bitwise XOR |
& | Bitwise AND |
<<, >> | Shifts |
+, – | Addition and subtraction |
*, /, //, % | Multiplication, division, remainder [8] |
+x, -x, ~x | Positive, negative, bitwise NOT |
** | Exponentiation [9] |
x[index], x[index:index], x(arguments…), x.attribute |
Subscription, slicing, call, attribute reference |
(expressions…), [expressions…], {key: value…}, `expressions…` |
Binding or tuple display, list display, dictionary display, string conversion |