Skip to content

Commit f95c68e

Browse files
committed
Merge pull request adafruit#473 from pfalcon/list-extend-iter
objlist: Make .extend accept arbitrary iterable.
2 parents b9e7ed4 + aa6666c commit f95c68e

2 files changed

Lines changed: 26 additions & 16 deletions

File tree

py/objlist.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ STATIC void list_print(void (*print)(void *env, const char *fmt, ...), void *env
3939
print(env, "]");
4040
}
4141

42+
STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) {
43+
mp_obj_t iter = mp_getiter(iterable);
44+
mp_obj_t item;
45+
while ((item = mp_iternext(iter)) != MP_OBJ_NULL) {
46+
mp_obj_list_append(list, item);
47+
}
48+
return list;
49+
}
50+
4251
STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
4352
// TODO check n_kw == 0
4453

@@ -50,13 +59,9 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
5059
case 1:
5160
{
5261
// make list from iterable
53-
mp_obj_t iterable = mp_getiter(args[0]);
62+
// TODO: optimize list/tuple
5463
mp_obj_t list = mp_obj_new_list(0, NULL);
55-
mp_obj_t item;
56-
while ((item = mp_iternext(iterable)) != MP_OBJ_NULL) {
57-
mp_obj_list_append(list, item);
58-
}
59-
return list;
64+
return list_extend_from_iter(list, args[0]);
6065
}
6166

6267
default:
@@ -173,18 +178,21 @@ mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) {
173178

174179
STATIC mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in) {
175180
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_list));
176-
assert(MP_OBJ_IS_TYPE(arg_in, &mp_type_list));
177-
mp_obj_list_t *self = self_in;
178-
mp_obj_list_t *arg = arg_in;
181+
if (MP_OBJ_IS_TYPE(arg_in, &mp_type_list)) {
182+
mp_obj_list_t *self = self_in;
183+
mp_obj_list_t *arg = arg_in;
184+
185+
if (self->len + arg->len > self->alloc) {
186+
// TODO: use alloc policy for "4"
187+
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + arg->len + 4);
188+
self->alloc = self->len + arg->len + 4;
189+
}
179190

180-
if (self->len + arg->len > self->alloc) {
181-
// TODO: use alloc policy for "4"
182-
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + arg->len + 4);
183-
self->alloc = self->len + arg->len + 4;
191+
memcpy(self->items + self->len, arg->items, sizeof(mp_obj_t) * arg->len);
192+
self->len += arg->len;
193+
} else {
194+
list_extend_from_iter(self_in, arg_in);
184195
}
185-
186-
memcpy(self->items + self->len, arg->items, sizeof(mp_obj_t) * arg->len);
187-
self->len += arg->len;
188196
return mp_const_none; // return None, as per CPython
189197
}
190198

tests/basics/list1.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
x.extend([100, 200])
1515
print(x)
16+
x.extend(range(3))
17+
print(x)
1618

1719
x += [2, 1]
1820
print(x)

0 commit comments

Comments
 (0)