эффективный алгоритм редактирования списка
У меня есть облако 3D-точек, сохраненное в двух списках. Пример с 5 точками (x, y, z): (3,3,3), (1,1,1), (4,4,4), (2,2,2), (5,5,5 ) -> Мои списки выглядят так:
z = [3, 1, 4, 2, 5] # the z values pts = [(3,3), (1,1), (4,4), (2,2), (5,5)] # the x and y values
Теперь я хочу исключить все значения, где значение z больше 3:
# what I want to receive: z = [3, 1, 2] pts = [(3,3), (1,1), (2,2)]
Мой алгоритм здесь:
k = -1 for i in range(len(z)): k += 1 if z[k] > h: z.pop(k) pts.pop(k) k -= 1
Это возвращает меня именно то, что я хочу – но это очень медленно (для> 100 000 значений). Я подумал о том, чтобы сначала отсортировать свой список через z.sort()
а затем сделать z = z [: index] – но когда я это сделаю для своего z-списка, тогда мой список pts все еще не отсортирован. И даже если бы я мог сортировать оба списка, мне также не нужно проходить длинный loop
чтобы найти индекс, где мое условие true
? Кто-нибудь знает более эффективное решение?
- Добавление списков и строк и импорт текущего года
- Python: поиск расстояний между полями списка
- Python удаляет подсписку в списке, если конкретный элемент внутри этого подсети
- Изменение элемента списка без изменения исходных значений
- найдите элемент первой последовательности, соответствующий критерию
z, pts = zip(*[(z, pt) for z, pt in zip(z, pts) if z <= 3]) print z, pts
Вывод
(3, 1, 2) ((3, 3), (1, 1), (2, 2))
С itertools:
from itertools import izip, ifilter
молчать вместе
zipped_coords = izip(z, pts)
фильтр (в сообщении вы указываете higher
, но результаты с вытеснением на самом деле ниже, сначала выбираются)
filtered_coords = ifilter(lambda x: x[0]>=3, zipped_coords )
расстегнуть молнию
znew, ptsnew = map(list, izip(*filtered_coords))
или все-в-одном oneliner
>>> znew, ptsnew = map(list, izip(*ifilter(lambda x: x[0]>=3, izip(z, pts)))) >>> print znew, ptsnew [3, 4, 5] [(3, 3), (4, 4), (5, 5)]
Поскольку вы удаляете элементы из списка при повторении, это алгоритм O (N ^ 2). Вы можете использовать простое понимание списка вместе с zip
чтобы сделать это в линейном времени.
z = [3, 1, 4, 2, 5] # the z values pts = [(3,3), (1,1), (4,4), (2,2), (5,5)] # the x and y values merged = zip(z, pts) filtered = [x for x in merged if x[0] <= 3] z, pts = zip(*filtered)
- как сделать нос для регистрации вывода дел для разделения файлов?
- Как получить флажки с помощью CustomTreeCtrl
- Как проверить, присутствует ли индекс списка или нет
- Is 'for x in array' всегда приводит к сортировке x?
- Python: как увидеть, содержит ли список последовательные номера
- Сравнение Python и слияние
- Присвоение элемента из списка массиву
- Как эффективно объединить список с запятыми и добавить «и» до последнего элемента
- Копирование содержимого файла в многомерный список в Python
- Установить операцию в python
- Преобразование этого списка в словарь с использованием Python