Сортировка как в Revit
Главная › Форумы › Задать вопрос › Сортировка как в Revit
- В этой теме 15 ответов, 6 участников, последнее обновление 7 лет, 4 месяца назад сделано Артем Манютин.
-
АвторСообщения
-
День добрый, у меня вопрос. В динамо строка с текстом почему то сортируется посимвольно (текст я убрать не могу, он также сортируется по алфавиту), то есть после 10 идёт 2. Мне нужно сделать всё как в ревите где двойка идёт после единицы. Думаю это популярная проблема, но на форумах ответ найти не смог.
http://dynamobim.org/forums/topic/list-sorting/
Вообще бы я в питоне сортанул бы чем возился бы с нодами.
На форуме по ссылке из строки убирается текст и сортируется как число, а у меня текст является неотъемлемой частью строки. Питон к сожалению не знаю
Получился такой скрипт.
Сложный. Индивидуальный под конкретную задачу.
К сожалению, сортировка она такая… Я проще пути не знаю
https://www.dropbox.com/s/zd1c7odnha5q4tl/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8.dyn?dl=0Ива Серж, огромное спасибо за скрипт, но он действительно очень индивидуальный. И он не работает, т.к. у меня в конце списка есть марка XCB235.12(1) которую Ревит прекрасно сортирует в нужное место в отличие от динамо. И если простым способом это не решаемо, то бог с ним. Спасибо ещё раз! )
в Python в 1 строчку и без регулярных выражений )) (но для читаемости лучше этот код записывать в несколько строк)
OUT = zip(*sorted(zip([int(i.split(".")[1]) for i in IN[0]], IN[0]), key = lambda lists: lists[0]))[1]
для тех, кто изучает python несколько слов про код:
– split разделяю по точке “.” и создаю новый список цифр (int переводит текст в цифры) (в нашем примере 10, 3, 2, 1, 11)
– zip соединяю 2 списка – наши цифры и исходный
– sorted key lambda – сортирую наш объединенный список, но по цифрам (lists[0])
– zip(*list)[1] – разъединяю объединенный список и получаю исходный отсортированный по цифрам
еще пример здесь
p.s. код не сортирует по цифрам до точки, т.е. не работает с В1.1, В2.1 ..не знал, что sorted может сразу по 2 параметрам сортировать..
тогда поправил свой код (уложился в 1 строку, не считая import):from operator import itemgetter OUT = zip(*sorted(zip([int(i.split(".")[0][1:]) for i in list1], [int(i.split(".")[1]) for i in list1], list1), key=itemgetter(0,1)))[2]
p.s. Если префикс (в данном примере буква “В”) будет состоять из нескольких букв, то нужно заменить [1:] на нужное количество букв
Питон сила) ну ты все же допиши код, чтобы количество символов в префиксе не имело значение, а то это мина замедленного действия, кто то обязательно пропустит мимо ушей твою ремарку.
И друзья, обратите внимание на эту конструкцию
list(iter(digs(i)))
это получение удобоваримого списка из любого итерируемого объекта. Зачастую при работе с объектами Ревит(импорт геометрии, импорт параметров) приходят интересные объекты, которые вроде являются списками, но не всегда обрабатываются обычными методами списков, бывает что обрабатываются нестабильно – вчера скрипт работал, а с утра перестал. Возможно вы уже сталкивались с такой проблемой. В данном случае я с помощью этого приема преобразовал (a,b) – tuple в [a,b] – listэто конечно уже треш, но в одну строку ))
from operator import itemgetter OUT = zip(*sorted(zip([("").join([i for i in p if i.isalpha()]) for p in [i.split(".")[0] for i in IN[0]]], [int(("").join([i for i in p if i.isdigit()])) for p in [i.split(".")[0] for i in IN[0]]], [int(i.split(".")[1]) for i in IN[0]], IN[0]), key=itemgetter(0,1,2)))[3]
p.s. не зависит от количества букв в префиксе и сортирует по алфавиту
update: для тех, кто хочет разобраться в коде выше, переписал в нормальном виде с комментариями
Legantmar, Khasan Mamaev спасибо за подробное объяснение как это работает!
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.