require list comprehensions to start with a for clause
This commit is contained in:
parent
2823f03a56
commit
46dfa5f4ed
|
@ -153,7 +153,7 @@ square brackets:
|
|||
|
||||
\begin{verbatim}
|
||||
list_display: "[" [listmaker] "]"
|
||||
listmaker: expression ( list_iter | ( "," expression)* [","] )
|
||||
listmaker: expression ( list_for | ( "," expression)* [","] )
|
||||
list_iter: list_for | list_if
|
||||
list_for: "for" expression_list "in" testlist [list_iter]
|
||||
list_if: "if" test [list_iter]
|
||||
|
@ -164,7 +164,8 @@ by providing either a list of expressions or a list comprehension.
|
|||
When a comma-separated list of expressions is supplied, its elements are
|
||||
evaluated from left to right and placed into the list object in that
|
||||
order. When a list comprehension is supplied, it consists of a
|
||||
single expression followed by one or more "for" or "if" clauses. In this
|
||||
single expression followed by at least one "for" clause and zero or more
|
||||
"for" or "if" clauses. In this
|
||||
case, the elements of the new list are those that would be produced
|
||||
by considering each of the "for" or "if" clauses a block, nesting from
|
||||
left to right, and evaluating the expression to produce a list element
|
||||
|
|
|
@ -1755,10 +1755,15 @@ item, then to the result and the next item, and so on. For example,
|
|||
|
||||
\subsection{List Comprehensions}
|
||||
|
||||
List comprehensions provide a concise way to create lists without
|
||||
resorting to use of the \function{map()} or \function{filter()}
|
||||
functions. The resulting construct tends often to be clearer than use
|
||||
of those functions.
|
||||
List comprehensions provide a concise way to create lists without resorting
|
||||
to use of \function{map()}, \function{filter()} and/or \keyword{lambda}.
|
||||
The resulting list definition tends often to be clearer than lists built
|
||||
using those constructs. Each list comprehension consists of an expression
|
||||
following by a \keyword{for} clause, then zero or more \keyword{for} or
|
||||
\keyword{if} clauses. The result will be a list resulting from evaluating
|
||||
the expression in the context of the \keyword{for} and \keyword{if} clauses
|
||||
which follow it. If the expression would evaluate to a tuple, it must be
|
||||
parenthesized.
|
||||
|
||||
\begin{verbatim}
|
||||
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
|
||||
|
@ -1771,6 +1776,17 @@ of those functions.
|
|||
[12, 18]
|
||||
>>> [3*x for x in vec if x < 2]
|
||||
[]
|
||||
>>> [{x: x**2} for x in vec]
|
||||
[{2: 4}, {4: 16}, {6: 36}]
|
||||
>>> [[x,x**2] for x in vec]
|
||||
[[2, 4], [4, 16], [6, 36]]
|
||||
>>> [x, x**2 for x in vec] # error - parens required for tuples
|
||||
File "<stdin>", line 1
|
||||
[x, x**2 for x in vec]
|
||||
^
|
||||
SyntaxError: invalid syntax
|
||||
>>> [(x, x**2) for x in vec]
|
||||
[(2, 4), (4, 16), (6, 36)]
|
||||
>>> vec1 = [2, 4, 6]
|
||||
>>> vec2 = [4, 3, -9]
|
||||
>>> [x*y for x in vec1 for y in vec2]
|
||||
|
|
|
@ -77,7 +77,7 @@ term: factor (('*'|'/'|'%') factor)*
|
|||
factor: ('+'|'-'|'~') factor | power
|
||||
power: atom trailer* ('**' factor)*
|
||||
atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
|
||||
listmaker: test ( list_iter | (',' test)* [','] )
|
||||
listmaker: test ( list_for | (',' test)* [','] )
|
||||
lambdef: 'lambda' [varargslist] ':' test
|
||||
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
|
||||
subscriptlist: subscript (',' subscript)* [',']
|
||||
|
|
|
@ -55,4 +55,5 @@ classdef
|
|||
[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
|
||||
[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
|
||||
good: got a SyntaxError as expected
|
||||
good: got a SyntaxError as expected
|
||||
[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]
|
||||
|
|
|
@ -578,6 +578,12 @@ try:
|
|||
except SyntaxError:
|
||||
print "good: got a SyntaxError as expected"
|
||||
|
||||
try:
|
||||
eval("[x if y]")
|
||||
print "FAIL: should have raised a SyntaxError!"
|
||||
except SyntaxError:
|
||||
print "good: got a SyntaxError as expected"
|
||||
|
||||
suppliers = [
|
||||
(1, "Boeing"),
|
||||
(2, "Ford"),
|
||||
|
|
|
@ -1043,7 +1043,7 @@ com_list_iter(struct compiling *c,
|
|||
static void
|
||||
com_list_comprehension(struct compiling *c, node *n)
|
||||
{
|
||||
/* listmaker: test list_iter */
|
||||
/* listmaker: test list_for */
|
||||
char tmpname[12];
|
||||
sprintf(tmpname, "__%d__", ++c->c_tmpname);
|
||||
com_addoparg(c, BUILD_LIST, 0);
|
||||
|
@ -1052,7 +1052,7 @@ com_list_comprehension(struct compiling *c, node *n)
|
|||
com_addopnamestr(c, LOAD_ATTR, "append");
|
||||
com_addopnamestr(c, STORE_NAME, tmpname);
|
||||
com_pop(c, 1);
|
||||
com_list_iter(c, n, CHILD(n, 0), tmpname);
|
||||
com_list_for(c, CHILD(n, 1), CHILD(n, 0), tmpname);
|
||||
com_addopnamestr(c, DELETE_NAME, tmpname);
|
||||
--c->c_tmpname;
|
||||
}
|
||||
|
@ -1060,8 +1060,8 @@ com_list_comprehension(struct compiling *c, node *n)
|
|||
static void
|
||||
com_listmaker(struct compiling *c, node *n)
|
||||
{
|
||||
/* listmaker: test ( list_iter | (',' test)* [','] ) */
|
||||
if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_iter)
|
||||
/* listmaker: test ( list_for | (',' test)* [','] ) */
|
||||
if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for)
|
||||
com_list_comprehension(c, n);
|
||||
else {
|
||||
int len = 0;
|
||||
|
|
|
@ -1317,7 +1317,7 @@ static state states_59[4] = {
|
|||
{1, arcs_59_3},
|
||||
};
|
||||
static arc arcs_60_0[2] = {
|
||||
{128, 1},
|
||||
{120, 1},
|
||||
{129, 1},
|
||||
};
|
||||
static arc arcs_60_1[1] = {
|
||||
|
@ -1340,7 +1340,7 @@ static arc arcs_61_3[1] = {
|
|||
{9, 4},
|
||||
};
|
||||
static arc arcs_61_4[2] = {
|
||||
{120, 5},
|
||||
{128, 5},
|
||||
{0, 4},
|
||||
};
|
||||
static arc arcs_61_5[1] = {
|
||||
|
@ -1361,7 +1361,7 @@ static arc arcs_62_1[1] = {
|
|||
{21, 2},
|
||||
};
|
||||
static arc arcs_62_2[2] = {
|
||||
{120, 3},
|
||||
{128, 3},
|
||||
{0, 2},
|
||||
};
|
||||
static arc arcs_62_3[1] = {
|
||||
|
@ -1622,7 +1622,7 @@ static label labels[130] = {
|
|||
{25, 0},
|
||||
{2, 0},
|
||||
{3, 0},
|
||||
{316, 0},
|
||||
{317, 0},
|
||||
{1, "lambda"},
|
||||
{314, 0},
|
||||
{307, 0},
|
||||
|
@ -1630,7 +1630,7 @@ static label labels[130] = {
|
|||
{309, 0},
|
||||
{1, "class"},
|
||||
{315, 0},
|
||||
{317, 0},
|
||||
{316, 0},
|
||||
{318, 0},
|
||||
};
|
||||
grammar _PyParser_Grammar = {
|
||||
|
|
Loading…
Reference in New Issue