Использование bisect в списке кортежей?

Я пытаюсь понять, как использовать bisect в списке кортежей, например

[(3, 1), (2, 2), (5, 6)]

Как я могу разделить этот список пополам в соответствии с [1] в каждом кортеже?

list_dict [(69, 8), (70, 8), ((65, 67), 6)]
tup1,tup2 (69, 8) (70, 8)
list_dict [((65, 67), 6)]
fst, snd ((65, 67),) (6,)

И я вставляю пополам

idx = bisect.bisect(fst, tup1[1]+tup2[1])

Что дает мне unorderable types: int() < tuple()


person user3157919    schedule 03.01.2014    source источник


Ответы (5)


Вы можете выделить значения в отдельные списки.

from bisect import bisect

data = [(3, 1), (2, 2), (5, 6)]
fst, snd = zip(*data)
idx = bisect(fst, 2)

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

person Jon Clements♦    schedule 03.01.2014
comment
Этот конкретный метод не работает для меня, так как я каждый раз обновляю кортежи, я объясню в редактировании - person user3157919; 03.01.2014
comment
@user3157919 user3157919 вам нужно убедиться, что то, что вы делите пополам, и то, с чем вы работаете, являются отдельными (и деление пополам должно быть сопоставимых типов), и соединить их позже, если это необходимо ... - person Jon Clements♦; 03.01.2014
comment
Основным преимуществом использования bisect является линейный поиск по времени. Копирование списка в линейном временном режиме означает, что вы также можете выполнять линейный поиск. - person Brent; 07.07.2020

В некоторых случаях просто

bisect(list_of_tuples, (3, None))

будет достаточно.

Поскольку None будет сравниваться меньше, чем любое целое число, это даст вам индекс первого кортежа, начинающегося как минимум с 3, или len(list_of_tuples), если все они меньше 3. Обратите внимание, что list_of_tuples отсортировано.

person Evgeni Sergeev    schedule 03.08.2015
comment
это не работает в Python 3. Если вы передадите точное число 3, вы получите TypeError: unorderable types: int() < NoneType(). НО bisect(list_of_tuples, (3, )) все будет в порядке. - person Jean-François Fabre; 16.01.2017

Проверьте нижний раздел документации: http://docs.python.org/3/library/bisect.html. Если вы хотите сравнить с чем-то еще, кроме самого элемента, вам следует создать отдельный список так называемых ключей. В вашем случае список целых чисел, содержащий только [1] кортежа. Используйте этот второй список для вычисления индекса пополам. Затем используйте это, чтобы вставить элемент в исходный (список кортежей) и ключ ([1] кортежа) в новый список ключей (список целых чисел).

person Thijs van Dien    schedule 03.01.2014
comment
Основным преимуществом использования bisect является линейный поиск по времени. Копирование списка в линейном временном режиме означает, что вы также можете выполнять линейный поиск. - person Brent; 07.07.2020
comment
@Brent Это зависит от того, сколько раз вы ищете. Моя идея заключается в том, что вы поддерживаете две структуры данных для совместной работы. С таким же успехом они оба могут начать пустыми. - person Thijs van Dien; 07.07.2020

Ответы, которые предлагают преобразовать входной список, побеждают цель деления пополам путем преобразования того, что должно быть O (log n), в операцию O (n). Лучшим решением является использование представления на входе:

class _list_view:
    def __init__(self, a, key):
        self.a = a
        self.key = key

    def __getitem__(self, index):
        return self.key(self.a[index])


def bisect_left(a, x, lo=0, hi=None, key=id):
    from bisect import bisect_left
    hi = hi or len(a)
    if key == id:
        return bisect_left(a, x, lo, hi)
    return bisect_left(_list_view(a, key), x, lo, hi)
person Brent    schedule 08.07.2020

Я столкнулся с той же проблемой. Я хранил список кортежей (file_id, word_frequency) и хотел получить список, отсортированный по второму элементу в кортеже, который равен word_frequency. Я провел небольшое исследование и выяснил, как python сравнивает кортежи, которые описаны здесь https://howtodoinjava.com/python/compare-tuples/.

По сути, он просматривает первый элемент двух кортежей и берет меньший. Если первые элементы одинаковы, то он сравнивает вторые значения и так далее.

Итак, что я сделал, так это поменял элементы в кортеже (word_frequency, file_id). Теперь я отсортировал свой список по частоте слов, используя деление пополам.

Надеюсь это поможет

person samsri    schedule 13.03.2020