仅使用用户名更改记录了解多个用户名更改的个人用户(不存在唯一ID)

时间:2017-02-04 12:05:57

标签: algorithm python-3.x data-structures

我有一个图论问题,涉及通过多个用户名更改分析用户(不幸的是,每个用户的唯一ID都没有保存)。

有一个用户名更改列表以及用户名更改的时间。格式为:'2017-01-01 02:00:00', 'previous_username', 'new_username'

目标是将每个用户的最新用户名链接到给定时间点。例如,我希望能够回答这个问题:在'previous_username'上拥有用户名'2016-12-31 00:00:00'的用户的当前用户名是什么?

我认识到这是一个图论问题,我正在寻找在python中解决它。请注意,用户可能多次更改了用户名。

2 个答案:

答案 0 :(得分:0)

嗯,你可以看到这是一个图论问题。但我认为最简单的方法是首先对列表进行排序 - 让我们称之为username_changes - 按时间进行,然后遍历它,类似于这个例子(没有经过测试t

username_changes.sort(key = lambda x: x[0])
from_time = '2016-12-31 00:00:00'
user_name = 'previous_username'
for row in username_changes:
    if row[0] >= from_time and row[1]==user_name:
        user_name = row[2]
print(user_name)

答案 1 :(得分:0)

这个问题不是图论问题。您正在寻找可以提供有关用户名的查询的数据结构。要快速实现此类搜索,需要进行一些索引。 一个简单的解决方案是拥有以下数据结构:

  • 为每个用户存储其过去用户名的列表,其中包含使用用户名的持续时间,
  • 将每个使用过的用户名映射到用户列表中使用的位置列表。

用户列表中的索引是用户的唯一ID。

像这样的东西(根本未经过测试):

from collections import defaultdict

class LogData:
  def __init__(self):
    self.users = []
    self.usernames = defaultdict(list)

  # Note: data should be filled in time sorted order!
  def add(self, previous_username, new_username, time):
    # Find is username know
    for i, username_list in enumerate(self.users):
      if username_list[-1]['username'] == previous_username:
        username_list[-1]['to_time'] = time
        self.usernames[new_username].append((i, len(username_list)))
        username_list.append(dict(username=new_username, from_time=time))
        return
    # First apearance of previous_username
    self.usernames[previous_username].append((len(self.users), 0))
    self.usernames[new_username].append((len(self.users), 1))
    self.users.append([
      dict(username=previous_username, to_time=time),
      dict(username=new_username, from_time=time),
    ])

  def current_username(self, username, time):
    for user_ind, i in self.usernames.get(username, []):
      d = self.users[user_ind][i]
      from_time = d.get('from_time')
      to_time = d.get('to_time')
      if (from_time is None or from_time <= time) and \
         (to_time is None or to_time >= time):
        return self.users[user_ind][-1]['username']