Страницы

Поиск по вопросам

четверг, 4 октября 2018 г.

Разбить элементы списка посимвольно

Здравствуйте!
Подскажите, пожалуйста, как можно разбить уловный список ['1', '22', '333'] по символам, т.е. чтобы получился список ['1', '2', '2', '3', '3', '3']
Заранее спасибо!


Ответ

На функциональщине в одну строчку:
reduce(lambda a, x: a + x, map(lambda x: list(x), ['1', '22', '333']))
Поясняю - reduce принимает на вход функцию, которая объединяет результаты разбиения списка функцией map. Map принимает на вход функцию и начальный массив, над каждым элементом массива выполняется данная функция. То же самое можно выразить следующим кодом:
>>> result_list = [] >>> for x in ['1', '22', '333']: ... for y in list(x): ... result_list.append(y) ... >>> print(result_list) ['1', '2', '2', '3', '3', '3']

Сравнение по скорости предложенных вариантов:
Вариант с использованием join и объединением в строку результата уделал всех. Оно и неудивительно — все операции здесь быстрые. Будет работать с любыми iterable объектами:
$python3 -m timeit "list(''.join(['1', '22', '333']))" 1000000 loops, best of 3: 0.318 usec per loop
Вариант с использованием генератора списка из ответа @jfs действительно работает быстро:
$python3 -m timeit "[char for s in ['1', '22', '333'] for char in s]" 1000000 loops, best of 3: 0.452 usec per loop
Вариант с использованием sum занимает третье место по скорости, однако по моему мнению, проигрывает в интуитивности:
$python3 -m timeit "sum([list(i) for i in ['1', '22', '333']], [])" 1000000 loops, best of 3: 0.984 usec per loop
Вариант на map-reduce является самым медленным. Почему я его использую? Потому что мне нравятся цепочки вызовов. Остальное — вкусовщина. Однако даже Гвидо ненавидит reduce (и вынес его в functools в python3)
$python3 -m timeit "from functools import reduce; reduce(lambda a, x: a + x, map(lambda x: list(x), ['1', '22', '333']))" 100000 loops, best of 3: 2.16 usec per loop
Вариант с collections покрывает все случаи, когда передаваемый объект может быть неитерируемым (число, например), однако цена за такое — большое время выполнения:
$python3 -m timeit "import collections
def it(obj): if isinstance(obj, collections.Iterable): for ob in obj: if isinstance(ob, collections.Iterable) and len(ob) > 1: yield from it(ob) else: yield ob else: yield obj
list(it(['1', 2, [2, 44, '123', ('qwe')], 2]))" 100000 loops, best of 3: 14.6 usec per loop

Комментариев нет:

Отправить комментарий