Найти - Пользователи
Полная версия: flatten без extend
Начало » Python для новичков » flatten без extend
1 2
wbt
Иногда возникает вот такая задача, есть список с одним уровнем вложенности, типа
a = [[1,2,3],[4,5,6],[7,8,9]]

в выражении
[x for x in a]
звёздочку никуда не добавить, как я понимаю

можно ли следующее:
>>> d = []
>>> [d.extend(x) for x in a]
[None, None, None]
>>> d
[1, 2, 3, 4, 5, 6, 7, 8, 9]

проделать в одну строчку, без дополнительных переменных (и покороче да поэлегантнее)
s0rg
а почему имеено в одну строчку?
Для случаев любой вложенности я использую свой велосипед:
def flattern(iterable):
    '''
    Makes iterable 'flat'
    >>> list(flattern([
    ...     (1, 2), set([3, 4]), 'test', 5
    ... ]))
    [1, 2, 3, 4, 'test', 5]
    >>> list(flattern([
    ...     (1, 2, 3, ),
    ...     ([
    ...         [4, 5],
    ...         [6, 7]],
    ...         8,
    ...         set([9, 10])
    ...     ),
    ...     (
    ...         'test1', ('test2', )
    ...     ),
    ...     666
    ... ]))
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'test1', 'test2', 666]
    >>> list(flattern('abc'))
    ['abc']
    '''
    if not hasattr(iterable, '__iter__'):
        yield iterable
        return
    for it in iterable:
        for i in flattern(it):
            yield i
примеры использования в комплекте )
sergeek
from functools import reduce
from operator import add
a = [[1,2,3],[4,5,6],[7,8,9]]
reduce(add, a[1:], a[0])
Out[4]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
from itertools import chain
list(chain.from_iterable(a))
Out[6]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
list(chain(*a))
Out[7]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
wbt
потому что подобная задача возникает “на месте”, когда думаешь, что неплохо бы прицепить такой паровоз и спустить в шаблон. в случае одной строчки - прицепил, не задумываясь, потратил 10 секунд и не отвлёкся от мысли. в ином случае нужно думать, что и как городить, и стоит ли вообще это городить такие задачи не планируются, а спонтанно обнаруживаются

да и вообще, можно ли для разных .update, .extend и прочих, которые работают “в себе”, возвращать результат в виде полученных данных? а то многие об это спотыкаются

а флатен красивый, спасибо, записал. красивее чем те, что я краем глаза цеплял. на конкурсе “слеза рубиста” я бы дал первое место
sergeek
sum(a, [])
Out[8]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
wbt
chain я покрутил, правда на другой задаче, получалось не так. как хотел, да и забросил его. спасибо за напоминание и за хороший пример.

from functools import reduce

это для python 3? или это какой-то особый reduce?

reduce(add, a[1:], a[0])

над этим буду сегодня весь день медитировать, перебирать разные варианты для разных задач. красиво, элегантно.
wbt
sergeek
sum(a, )

Гениально и непостижимо! Этот человек окутал весь Лондон, а о нём до сих пор никто ничего не знает!
s0rg
sergeek
Это работает _только_ для списка чисел, к сожалению
wbt
# -*- coding: utf-8 -*-
a = [dict(t=['1z','2y','x3']),dict(t=['four','fif','sikz']),dict(t=[u'сэм',u'восэм',u'дэвять'])]
print sum([x['t'] for x in a],[])

['1z', '2y', 'x3', 'four', 'fif', 'sikz', u'\u0441\u044d\u043c', u'\u0432\u043e\u0441\u044d\u043c', u'\u0434\u044d\u0432\u044f\u0442\u044c']
sergeek
s0rg
Это работает _только_ для списка чисел, к сожалению
какой вариант?
вроде ок все
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB