将用户帐户映射到日期和排序的日期列表返回索引的映射,用户的日期在排序日期列表中有效

时间:2017-01-18 03:12:04

标签: 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, 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])

使用bisect模块的版本

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])

0 个答案:

没有答案