Python: Search a sorted list of tuples

ぃ、小莉子 提交于 2021-01-28 09:50:26

问题


Useful information:

For information on how to sort a list of various data types see: How to sort (list/tuple) of lists/tuples?

.. and for information on how to perform a binary search on a sorted list see: Binary search (bisection) in Python

My question:

How can you neatly apply binary search (or another log(n) search algorithm) to a list of some data type, where the key is a inner-component of the data type itself? To keep the question simple we can use a list of tuples as an example:

x = [("a", 1), ("b",2), ("c",3)]
binary_search(x, "b") # search for "b", should return 1
# note how we are NOT searching for ("b",2) yet we want ("b",2) returned anyways

To simplify even further: we only need to return a single search result, not multiple if for example ("b",2) and ("b",3) both existed.

Better yet:

How can we modify the following simple code to perform the above operation?

from bisect import bisect_left

def binary_search(a, x, lo=0, hi=None):  # can't use a to specify default for hi
    hi = hi if hi is not None else len(a)  # hi defaults to len(a)   
    pos = bisect_left(a, x, lo, hi)  # find insertion position
    return (pos if pos != hi and a[pos] == x else -1)  # don't walk off the end

PLEASE NOTE: I am not looking for the complete algorithm itself. Rather, I am looking for the application of some of Python's standard(ish) libraries, and/or Python's other functionalities so that I can easily search a sorted list of some arbitrary data type at any time.

Thanks


回答1:


Take advantage of how lexicographic ordering deals with tuples of unequal length:

# bisect_right would also work
index = bisect.bisect_left(x, ('b',))

It may sometimes be convenient to feed a custom sequence type to bisect:

class KeyList(object):
    # bisect doesn't accept a key function, so we build the key into our sequence.
    def __init__(self, l, key):
        self.l = l
        self.key = key
    def __len__(self):
        return len(self.l)
    def __getitem__(self, index):
        return self.key(self.l[index])

import operator
# bisect_right would *not* work for this one.
index = bisect.bisect_left(KeyList(x, operator.itemgetter(0)), 'b')



回答2:


What about converting the list of tuples to a dict?

>>> d = dict([("a", 1), ("b",2), ("c",3)])
>>> d['b'] # 2


来源:https://stackoverflow.com/questions/45155345/python-search-a-sorted-list-of-tuples

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!