将字符串列表转换为单个模式

时间:2014-07-14 20:29:28

标签: python redis

我有一个遵循特定模式的字符串列表。这是一个例子

['ratelimiter:foobar:201401011157',
 'ratelimiter:foobar:201401011158',
 'ratelimiter:foobar:201401011159',
 'ratelimiter:foobar:201401011200']

我正在尝试使用blob模式来代表此列表,如下所示

'ratelimiter:foobar:201401011*

我提前知道前两个字段。第三个字段是时间戳,我想找到它们开始与列中其他值具有不同值的列。

在给定的示例中,时间戳范围为2014-01-01-11:57到2014-01-01-12:00,而不同的列是第三列到最后一列,其中1更改为2.如果我可以找到,然后我可以将字符串切片到[:-3] += '*'(对于这个例子)

每当我尝试解决这个问题时,我最终都会遇到循环。我觉得这样做有更好的方法。

也许有人知道使用redis更好的方法。我这样做是因为我试图从redis获取密钥而我不想为每个密钥发出请求,而是使用模式参数发出批处理请求。也许有更好的方法可以做到这一点,但还没有找到任何东西。

由于

3 个答案:

答案 0 :(得分:2)

这就是我要做的:

  1. 将时间戳转换为数字
  2. 找到最大值和最小值(如果您的列表未订购)
  3. 取最大值和最小值之间的差值并将其转换回模式。
  4. 例如,在您的情况下,max和min之间的差值为43.并且min已经是57,您可以快速扣除如果min以*** 157结束,则max应该是*** 200。你知道模式

答案 1 :(得分:2)

保持模式的东西(转换为时间戳可能是最好的),我会这样做以找到最长的前缀:

items = ['ratelimiter:foobar:201401011157',
 'ratelimiter:foobar:201401011158',
 'ratelimiter:foobar:201401011159',
 'ratelimiter:foobar:201401011200']

print items[0][:[len(set(x)) == 1 for x in zip(*items)].index(False)] + '*'
# ratelimiter:foobar:201401011*

其中读作:切割items的第一个元素,其中items的所有第n个元素不再等于。

如果i上的所有元素在[len(set(x)) == 1 for x in zip(*items)]上相等,则

items将返回布尔值为True的列表

答案 2 :(得分:1)

你几乎从不想使用' *' Redis中的参数在生产中因为它非常慢 - 比在绝大多数情况下单独请求每个键要慢得多。除非您要求这么多密钥,否则您的瓶颈会成为您通过网络传输的大量数据(在这种情况下,您应该将内容转换为Lua并运行逻辑服务器端),pipeline真的是你想要的。

您想要管道的原因是您现在可能会受到在单独的跃点中在Redis服务器之间来回传输数据的成本的影响。相比之下,管道将一系列命令排队以对抗Redis,然后在您准备就绪时立即执行它们。假设您正在使用redis-py(如果您不是,那么您真的应该这样),r是您与Redis服务器的连接,您可以这样做:

r = redis.Redis(...)
pipe = r.pipeline()
items = ['ratelimiter:foobar:201401011157',
 'ratelimiter:foobar:201401011158',
 'ratelimiter:foobar:201401011159',
 'ratelimiter:foobar:201401011200']
for item in items:
    pipe.get(item)
#all the values for each item you're getting from Redis will be here.
item_values = pipe.execute()

注意:这只会对Redis进行一次调用,并且比单独获取每个值或运行模式选择要快得多。

到目前为止,所有其他答案都是很好的Python答案,但您正在处理Redis问题。你需要一个Redis的答案。