Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用户帐户到日期的映射和排序日期列表返回索引的映射。按用户排序的日期有效地位于排序日期列表中_Python_Algorithm - Fatal编程技术网

Python 用户帐户到日期的映射和排序日期列表返回索引的映射。按用户排序的日期有效地位于排序日期列表中

Python 用户帐户到日期的映射和排序日期列表返回索引的映射。按用户排序的日期有效地位于排序日期列表中,python,algorithm,Python,Algorithm,我正在复制Facebook的聊天阅读接收系统。我写了一些我认为有效的基本代码。然而,我的老板认为这会很慢。我没有算法训练。如果数字位于排序列表中的两个数字之间,并且索引是中间对中第一个数字的索引,那么返回索引到数字的映射的最有效方法是什么 # Given say {"a": 3, "b": 10, "c": 7, "d": 19} and [1,5,15] return {0: ["a"], 1: ["b", "c"], 2: ["d"]} def find_read_to(read_dates

我正在复制Facebook的聊天阅读接收系统。我写了一些我认为有效的基本代码。然而,我的老板认为这会很慢。我没有算法训练。如果数字位于排序列表中的两个数字之间,并且索引是中间对中第一个数字的索引,那么返回索引到数字的映射的最有效方法是什么

# Given say {"a": 3, "b": 10, "c": 7, "d": 19} and [1,5,15] return {0: ["a"], 1: ["b", "c"], 2: ["d"]}
def find_read_to(read_dates, message_dates):
    read_indexes_to_user_ids = {}
    for user_id in read_dates:
        for i, date in enumerate(message_dates):
            last_index = i + 1 == len(message_dates)
            next_index = -1 if last_index else i + 1
            if last_index or (read_dates[user_id] >= date and read_dates[user_id] < message_dates[next_index]):
                if i in read_indexes_to_user_ids:
                    read_indexes_to_user_ids[i].append(user_id)
                else:
                    read_indexes_to_user_ids[i] = [user_id]
                break
    return read_indexes_to_user_ids

find_read_to({"a": 3, "b": 10, "c": 7, "d": 19}, [1,5,15])

可以做一些事情来提高算法的效率,但是如果
message\u dates
很大,那么内部循环就是一个杀手。查看二分法模块,以获得更有效的搜索方法。@PM2Ring谢谢,我用使用二分法模块的代码编辑了我的问题
import bisect
def find_read_to(read_dates, message_dates):
    read_indexes_to_user_ids = {}
    user_ids, read_dates = zip(*read_dates.items())
    def find_between(read_date):
        answer = bisect.bisect_left(message_dates, read_date)
        answer -= 1
        if answer == -1:
            return None
        return answer
    indexes_for_read_up_to = map(find_between, read_dates)
    for i, index_for_read_up_to in enumerate(indexes_for_read_up_to):
        user_id = user_ids[i]
        if index_for_read_up_to is None:
            continue
        if index_for_read_up_to in read_indexes_to_user_ids:
            read_indexes_to_user_ids[index_for_read_up_to].append(user_id)
        else:
            read_indexes_to_user_ids[index_for_read_up_to] = [user_id]
    return read_indexes_to_user_ids

find_read_to({"a": 3, "b": 10, "c": 7, "d": 19}, [1,5,15])