LINUX.ORG.RU

[Python] Преобразовать один массив

 


0

1

Никак не соображу как на питоне привести следующую матрицу:

[['A',  2.58,  2.88],
 ['B',  2.96,  3.25],
 ['C',  3.3,   3.5],
 ['A',  2.58,  2.88],
 ['B',  2.96,  3.25],
 ['C',  3.3,   3.5],
 ['A',  2.58,  2.88],
 ['B',  2.96,  3.25],
 ['C',  3.3,   3.5],]

К такому виду:

[[[2.58,  2.88], [2.58,  2.88], [2.58,  2.88]],
 [[2.96,  3.25], [2.96,  3.25], [2.96,  3.25]],
 [[3.3,   3.5],  [3.3,   3.5],  [3.3,   3.5]],]

Т.е. первый элемент в каждом массиве по сути есть индекс по которому группируются элементы во второй матрице. Мой вариант с тупым перебором массива и формированием рядом нового мне не нравится - есть подозрение, что существует какой-то более прямой путь. Буду очень благодарен, если кто-то поможет.

★★★

100500 вариантов

L = [...] #исходный массив
D = {}
for i in L : D.setdefault(i[0],[]).append(i[1:])
R = D.items() #результат

В функц стиле не очень, но тож можно

reduce( lambda D, i : ( D.setdefault(i[0],[]).append(i[1:]), D )[1], L, {} ).items()

В общем через словарь будет лучше всего.

AIv ★★★★★
()
Ответ на: комментарий от AIv

reduce( lambda D, i : ( D.setdefault(i[0],[]).append(i[1:]), D )[1], L, {} ).items()

Бле, мы же не хотим, что бы питон ненавидели и спрыгивали на ЛИПС?))) Нее?

#!/usr/bin/env python

A = [['A',  2.58,  2.88],
 ['B',  2.96,  3.25],
 ['C',  3.3,   3.5],
 ['A',  2.58,  2.88],
 ['B',  2.96,  3.25],
 ['C',  3.3,   3.5],
 ['A',  2.58,  2.88],
 ['B',  2.96,  3.25],
 ['C',  3.3,   3.5],]


def doit():
    global A
    result = dict()
    for a in A:
        if(a[0] not in result):
            result[a[0]]= list()
        result[a[0]].append(a[1:])
    return result.values()

if(__name__=='__main__'):
    for item in  doit():
        print item # с округлением надеюсь сами разберетесь
anonymous
()
Ответ на: комментарий от pylin

> numpy

Убейся ап стену, numpy не для таких задач.)))

anonymous
()
Ответ на: комментарий от AIv

> Это типа такой конкурс «кто предложит ТС-у наиболее заморочный вариант»?;-)

Ну если кто предложит более понятный вариант для ньюби чем мой, наверно даже поставлю пиво.)))

anonymous
()
Ответ на: комментарий от AIv

ВАХ! Но твой вариант в функциональном стиле как бы того, не прокатывает. Разбираться влом, пятница, пиво. Давай уж в ЛОР коде с «if(__name__=='__main__'):» что бы народ не сомневался с твоем честном имени!)))

anonymous
()
Ответ на: комментарий от anonymous
aiv@aivbook:~/tmp$ python
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> L=[['A',  2.58,  2.88],
...  ['B',  2.96,  3.25],
...  ['C',  3.3,   3.5],
...  ['A',  2.58,  2.88],
...  ['B',  2.96,  3.25],
...  ['C',  3.3,   3.5],
...  ['A',  2.58,  2.88],
...  ['B',  2.96,  3.25],
...  ['C',  3.3,   3.5],]
>>> reduce( lambda D, i : ( D.setdefault(i[0],[]).append(i[1:]), D )[1], L, {} ).values()
[[[2.5800000000000001, 2.8799999999999999], [2.5800000000000001, 2.8799999999999999], [2.5800000000000001, 2.8799999999999999]], [[3.2999999999999998, 3.5], [3.2999999999999998, 3.5], [3.2999999999999998, 3.5]], [[2.96, 3.25], [2.96, 3.25], [2.96, 3.25]]]
>>> 

ТС не нуб - он как то эту задачу решил (видимо криво, в твоем стиле;-)) и сюда пришел с вопросом - как эту задачу решить прально. А ты ему суешь какую то ф-ю, принимающую данные через глобальный параметр, да еще работающую дико медленно (бол хреновым вариантом было только список взять а не словарь), да еще эту обвеску с __main__ зачем то вклячил. Фи... ;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv

А у тебя типо того, не через глобальную переменную «L», не да?))))

anonymous
()
Ответ на: комментарий от AIv

и да еще через timeit прогони, для пущего кайфа и покажы это всё ньюби.

И чего он тебе после этого скажет на «lambda D, i: ( D.setdefault(i[0],[]).append(i[1:]), D )[1], L, {} ).values()»?)))

Особенно если не читал «Структура и интерпритация компьютерных программ». А? как ты думаешь, как далеко он тебя пошлет? И как не печально вместе с питоном.:(

anonymous
()
Ответ на: комментарий от anonymous

сикп тут не причем. код avl с редьюсом просто отстойный. Так пишут люди дорвавшиеся до нормального языка и пытающиеся уместить все свои знания в 1 строчке.

anonymous
()
Ответ на: комментарий от pylin

Я уже успел посмотреть на numpy и там действительно хорошие функции для работы с матрицами, но с ходу не понял какая именно функция нужна мне. Читал референс - живых похожих примеров очень не хватает.

BigAlex ★★★
() автор топика
Ответ на: комментарий от anonymous

Это псевдокод. Я просто пытаюсь наглядно преподнести задачу. В коде все выглядит иначе - вообще, изначально это задача достать данные с публичного WSDL, привести их к удобоваримому виду и нарисовать по этим числам графики через соответсвующую библиотеку.

BigAlex ★★★
() автор топика
Ответ на: комментарий от anonymous

reduce нужен не для умещения всего в одной строчке, а для перевода цикла из питона в С - быстрее работает (если верить аффтарам). Это раз.

В коде ананимуса (я в вас ребят уже запутался, пеп8 асилил а регистрацию на ЛОРе нет?) нет setdefault-a, эта ф-я как раз для задачи ТС-а, это два.

ТС не нуб, а вот навешивать какие то лишние конструкции в тривиальном примере - это моветон, это три.

А у тебя типо того, не через глобальную переменную «L», не да?))))

В моем случае L может быть ЛЮБОЙ переменной. В твоем - сам сказал global A, никто тя за язык не тянул деточка.

AIv ★★★★★
()
Ответ на: комментарий от BigAlex

Если размер данных сравнительно невелик а производительность не важна, забудьте про numpy и делайте ручками - проще будет, питон достаточно высокоуровневый язык. Если данных оочень много (или производительность ооочень важна) - делайте опять таки ручками ф-ии на С/С++/fortran и т.д. и импортируйте в питон. numpy актуальна для каких то промежуточных случаев, или когда нужны какие то хитрые алгоритмы к-е там уже есть а самому писать влом.

Для рисования (если еще не выбрали) - берите MathGL, у нее есть питоновский интерфейс и де-факто это наиболее продвинутый графопостроитель на сегодняшний день. Для обычных двумерных графиков с ним только gnuplot может тягаться, для поверхностей и трехмерных полей гнуплот уже сливает и по кол-ву вариантов и по производительности.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Пеп8 не осилил ты — это раз.

Редьюс быстрей не работает — это два.

Наконец, я не говорил про код анлнимуса, а говорил что твой пример с редюсом — говнокод, и дело тут не в нуб /ненуб.

anonymous
()
Ответ на: комментарий от anonymous

> Редьюс быстрей не работает — это два.

Виноват, и правда в данном случае редьюс медленней. ОК, может предложишь свой вариант решения с ФП (за один проход списка)?

AIv ★★★★★
()
Ответ на: комментарий от AIv

> reduce нужен не для умещения всего в одной строчке, а для перевода цикла из питона в С - быстрее работает (если верить аффтарам).

Я смотрю ты так и не замерил таймитом свой примерчик?)))

нет setdefault-a, эта ф-я как раз для задачи ТС-а, это два.

setdefault? Не вижу в этой функции ничего особого, что бы истово на неё ..., уж простите.

В моем случае L может быть ЛЮБОЙ переменной.

Именно любой, благодаря чему глобальная L видна в люмде, знаешь хоть?)))

В твоем - сам сказал global A, никто тя за язык не тянул деточка.

Я не понял, чего ты так буйно возрадовался? Тебе не нравиться фишка с использованием global. Ну это как бы твои личные проблемы.

anonymous
()
Ответ на: комментарий от anonymous
#!/usr/bin/python
import time
L = [ [ i%1024,i ] for i in xrange(100000) ]

t0 = time.time()
D1 = {}
for i in L : D1.setdefault(i[0],[]).append(i[1:])
t1 = time.time()

D2 = reduce( lambda D, i : ( D.setdefault(i[0],[]).append(i[1:]), D )[1], L, {} ).values()
t2 = time.time()

result = dict()
for a in L:
    if(a[0] not in result):
        result[a[0]]= list()
    result[a[0]].append(a[1:])
t3 = time.time()

print t1-t0, t2-t1, t3-t2
aiv@aivbook:~/tmp$ python ./test.py
0.241786956787 0.315858125687 0.329551935196

setdefault? Не вижу в этой функции ничего особого, что бы истово на неё ..., уж простите.

Не прощу. Увидел? Твой вар еще медленнее моего говно-редьюса. Я не говорю про размер и наглядность.

Именно любой, благодаря чему глобальная L видна в люмде, знаешь хоть?)))

В лямбде L не фигурировала, хотя и видна. Использование глобальных переменных без острой необходимости это первый и весьма явный признак говнокода, и как в нем пробелы расставлены уже неважно - НИКОГДА ТАК НЕ ДЕЛАЙ. Чего б тебе не передать туда A как аргумент?

AIv ★★★★★
()
Ответ на: комментарий от AIv

По секрету: твой редюс ничего общего с ФП не имеет, т.к у тебя там есть детруктивный append. И с точке зрения ФП, раз уж ты так настаиваешь, твой код еще большее гавно.


// Правильный анонимус, говоривший, про пеп8 и говнокод

anonymous
()
Ответ на: комментарий от anonymous

[code=python]
d1 = {}
for i in L:
d1.setdefault(i[0], []).append(i[1:])
[/code]
В 150 раз лучше редюса.

anonymous
()
Ответ на: комментарий от AIv

> ОК, может предложишь свой вариант решения с ФП (за один проход списка)?

Нет не предложу, задача в топике стояла другая.)))

Тем более я не говорил, что-то плохое про твой вариант, кроме что нихера непонятно и медленно? Сделать более непонятнее и медленнее, я не смогу.)))

Как вариант, можно покастовать ЛИСПеров, у них получится.

anonymous
()
Ответ на: комментарий от anonymous

Слыш. Конь. ты подписывайся, не к тебе обрашались.

Avl это неправильный анонимус.

//злой анонимус

anonymous
()
Ответ на: комментарий от AIv

> Твой вар еще медленнее моего говно-редьюса. Я не говорю про размер и наглядность.

Чё-чё? Ты сказал, что мой пример менее наглядный чем твой? Да ты упоролся.

Кстати я тебе не говорил, что мой код быстрее. Я просто хотел, что бы ты увидел, что твой в типо «функциональном стиле», не хавает его на порядки.

НИКОГДА ТАК НЕ ДЕЛАЙ.

Наивный мальчик, ты увидел пример в котором я заюзал global для наглядности, то это не дает тебе право учить дядю как не нужно писать говнокод капсом.)))

Лучше своим стилем кодирования озаботься. Иначе проклятия коллег, которым доведется разбираться с твоими поделиями серьёзно подпортят твою карму.

anonymous
()
Ответ на: комментарий от anonymous

> Слыш. Конь. ты подписывайся, не к тебе обрашались.

Слыш лошадь!))) Во всех моих постах есть подпись. Если Avl не догоняет с кем беседует, это чисто его проблем.

//добрый анонимус )))

Догнал про подпись? Неее?)))

anonymous
()
Ответ на: комментарий от anonymous

так его и до шизофрении довести можно

anonymous
()
Ответ на: комментарий от anonymous

> Чё-чё? Ты сказал, что мой пример менее наглядный чем твой? Да ты упоролся.

Да, менее наглядный. И, повторюсь - ТС хотел увидеть правильное решение, а не какое нибудь.

А отключу ка я тут анонимные комменты, а то развелось вас тут...

AIv ★★★★★
()
Ответ на: комментарий от AIv

Это не научит тебя программировать, если после двух упоминаний pep8. Ты опять выложил ублюдочный код

anonymous
()
Ответ на: комментарий от anonymous

В С есть штук пять стилей оформления кода, у каждого есть свои сторонники, и они друг с другом грызутся. Я не считаю пеп8 истиной в последней инстанции, и оформляю код так, как мне это удобно. Мои коллеги, работающие с моим кодом, претензий мне не высказывали, им тоже удобно.

И перефразируя Тарантино: Ты что, где то видел тут вопрос - что Вы, уважаемы Анониумс, думаете о стиле программирования AIv? Нет, ты его тут не видел. А знаешь почему ты его тут не видел? Потому что его тут никто не задавал. Потому что тут вообще всем похрену что ты думаешь, тут ВООБЩЕ НИКОГО ТВОЕ МНЕНИЕ НЕ ИНТЕРЕСУЕТ. И меня в том числе;-)

AIv ★★★★★
()
Ответ на: комментарий от anonymous

Нет проблем;-)

ЗЫ. Первый раз за мою бытность на ЛОР-е анонимус вдруг извинился. К чему бы это? Неушто виндовс8 сделают на основе дебиана 6?;-)

AIv ★★★★★
()
Ответ на: комментарий от unC0Rr

Анонимус един, как синглтон или электрон Дирака. Просто он очень быстро прыгает от компа к компу, и ему самому кажется что его много;-)))

AIv ★★★★★
()
Ответ на: комментарий от AIv

> да еще эту обвеску с __main__ зачем то вклячил

Кстати, кто мне объяснит, зачем нужна эта строчка? Никогда не понимал. Всё и без неё замечательно работает же.

pevzi ★★★★★
()
Ответ на: комментарий от pevzi

Типа если модуль является головным, то что то в нем делается, если нет то только определятся ф-ии, классы и какие то глобальные переменные.

ИМНО дурь и зло страшное - поведение модуля не должно (за очень редкими исключениями) зависеть от того как ты его тащишь, а функции и какие то действия всегда надо разносить по разным модулям (если речь идет о сложном проекте). А то такие сюрпризы иногда бывают...

AIv ★★★★★
()
Ответ на: комментарий от AIv

А, спасибо. В принципе, я того же мнения.

pevzi ★★★★★
()
Ответ на: комментарий от unC0Rr

> Может это другой анонимус :)

Совершенно верно, у меня даже есть подозрение, что это он разлогинился и сам написал (видимо захотел сделать себе приятно))).

anonymous
()
Ответ на: комментарий от AIv

> Просто он очень быстро прыгает от компа к компу, и ему самому кажется что его много;-)))

Похоже у тебя началось расстройство психики.)))

anonymous
()
Ответ на: комментарий от pevzi

Чтобы программу можно было либо запускать как скрипт (при __name__ == '__main__'), выделяя в такой ветке if некий инициализирующий код (часто туда вставляют запуск всяких юнит(док)тестов), либо импортировать как модуль. Выглядит, конечно, коряво, зато даёт определенную гибкость, взять те же тесты. А вот нужна она или нет, решать программисту.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.