Самый простой способ классифицировать эти значения? - PullRequest
0 голосов
/ 06 марта 2020

У меня есть список высот слоя, в который я хочу отсортировать различные значения z. Список должен оставаться в порядке убывания, а функция должна возвращать индекс слоя, которому принадлежит значение z.

Например, для layers = [10,9,8,7] значение 9 должно быть возвращено как 1, так как это индекс его слоя, значение 8.5 также должно быть возвращено как 1, значение 8 должно возвращать 2, 7.9 возвращает 2 и т. д.

Функция, которую я написал, выдает ошибку, когда ищет индекс вне длины списка для последнего слоя.

def less_than(layers,z):

    index = 0
    current = layers[index]

    while current>z:
        index += 1
        current = layers[index]

    return(index-1)

Итак, каков наилучший метод для создания такой функции с этими свойствами?

Ответы [ 4 ]

1 голос
/ 06 марта 2020

Вот решение, использующее bisect:

import bisect


class ReverseAccessor:
    def __init__(self, ls):
        self.ls = ls

    def __getitem__(self, item):
        return self.ls[-(item) - 1]

    def __len__(self):
        return len(self.ls)


def less_than(layers, z):
    index = len(layers) - (bisect.bisect(ReverseAccessor(layers), z)) - 1
    if layers[index + 1] == z:
        return index + 1
    return index

Это немного сложнее, чем ваше решение, но теоретически будет работать лучше, когда список станет большим. Мы определяем пользовательский объект, который содержит ссылку на исходный список и переводит обращения к элементам в их обращенную форму. Таким образом, мы можем сохранить сложность O (log n) bisect.

0 голосов
/ 06 марта 2020

Если ваш список слоев не так уж велик, и вы не особо заботитесь о O (logN) деления, вот очень простое решение O (N):

import math

layers.index(math.ceil(z))

ceil округляет z вверх, а затем мы используем встроенный метод списка, чтобы найти индекс элемента.

Вы можете заменить ceil(z) на int(z + 0.5), если вы не хотите импортировать.

0 голосов
/ 06 марта 2020

Решение на основе np.where:

import numpy as np 

layers = [10,9,8,7]

def less_than(layers, z):
    return np.max(np.where(np.array(layers)>=z))

Пример:

less_than(layers, 8.5)

вывод:

1

0 голосов
/ 06 марта 2020

Ваша функция в порядке, вам просто нужно убедиться, что вы не пытаетесь получить доступ к элементам, которые не существуют (я также немного упростил это):

def less_than(layers, z):
    index = 0
    while index < len(layers) and layers[index] > z:
        index += 1
    return index - 1

Помимо ошибки индекса это должно вести себя так же, как ваша функция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...