diff -r 020364d3e359 Include/opcode.h --- a/Include/opcode.h Sat Feb 25 16:24:59 2012 +0100 +++ b/Include/opcode.h Sat Feb 25 18:20:43 2012 -0500 @@ -149,7 +149,7 @@ #define SET_ADD 146 #define MAP_ADD 147 - +#define BUILD_LIST_FROM_ARG 148 enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; diff -r 020364d3e359 Lib/opcode.py --- a/Lib/opcode.py Sat Feb 25 16:24:59 2012 +0100 +++ b/Lib/opcode.py Sat Feb 25 18:20:43 2012 -0500 @@ -188,5 +188,6 @@ EXTENDED_ARG = 145 def_op('SET_ADD', 146) def_op('MAP_ADD', 147) +def_op('BUILD_LIST_FROM_ARG', 148) del def_op, name_op, jrel_op, jabs_op diff -r 020364d3e359 Python/ceval.c --- a/Python/ceval.c Sat Feb 25 16:24:59 2012 +0100 +++ b/Python/ceval.c Sat Feb 25 18:20:43 2012 -0500 @@ -2187,7 +2187,7 @@ break; case BUILD_LIST: - x = PyList_New(oparg); + x = PyList_New(oparg); if (x != NULL) { for (; --oparg >= 0;) { w = POP(); @@ -2198,6 +2198,19 @@ } break; + case BUILD_LIST_FROM_ARG: + x = POP(); + Py_ssize_t length = _PyObject_LengthHint(x, 0); + if (length != -1) { + w = PyList_New(length); + if (w != NULL) { + Py_SIZE(w) = 0; + PUSH(w); + PUSH(x); + } + } + break; + case BUILD_SET: x = PySet_New(NULL); if (x != NULL) { diff -r 020364d3e359 Python/compile.c --- a/Python/compile.c Sat Feb 25 16:24:59 2012 +0100 +++ b/Python/compile.c Sat Feb 25 18:20:43 2012 -0500 @@ -822,6 +822,8 @@ return 1-oparg; case BUILD_MAP: return 1; + case BUILD_LIST_FROM_ARG: + return 1; case LOAD_ATTR: return 0; case COMPARE_OP: @@ -2590,7 +2592,7 @@ static int compiler_listcomp_generator(struct compiler *c, asdl_seq *generators, - int gen_index, expr_ty elt) + int gen_index, expr_ty elt, int single) { /* generate code for the iterator, then each of the ifs, and then write to the element */ @@ -2610,6 +2612,9 @@ l = (comprehension_ty)asdl_seq_GET(generators, gen_index); VISIT(c, expr, l->iter); + if (single) { + ADDOP_I(c, BUILD_LIST_FROM_ARG, 0); + } ADDOP(c, GET_ITER); compiler_use_next_block(c, start); ADDOP_JREL(c, FOR_ITER, anchor); @@ -2626,7 +2631,7 @@ } if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_listcomp_generator(c, generators, gen_index, elt)) + if (!compiler_listcomp_generator(c, generators, gen_index, elt, 0)) return 0; /* only append after the last for generator */ @@ -2646,10 +2651,15 @@ static int compiler_listcomp(struct compiler *c, expr_ty e) { + int single; assert(e->kind == ListComp_kind); - ADDOP_I(c, BUILD_LIST, 0); + single = (asdl_seq_LEN(e->v.ListComp.generators) == 1 && + !asdl_seq_LEN(((comprehension_ty)asdl_seq_GET(e->v.ListComp.generators, 0))->ifs)); + if (!single) { + ADDOP_I(c, BUILD_LIST, 0); + } return compiler_listcomp_generator(c, e->v.ListComp.generators, 0, - e->v.ListComp.elt); + e->v.ListComp.elt, single); } /* Dict and set comprehensions and generator expressions work by creating a