2014-07-14 41 views
1

我有一个遵循特定模式的字符串列表。这里的将字符串列表转换为单个模式

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

我想用那将代表像下面

'ratelimiter:foobar:201401011* 

我事先知道前两个字段此列表中的BLOB模式落得一个例子。第三个字段是一个时间戳,我想查找它们开始与列中其他值不同的值的列。

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

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

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

感谢

回答

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个元素不再等于。

[len(set(x)) == 1 for x in zip(*items)]将返回布尔名单是真实的我,如果我在所有的元素都是跨items

2

这是我会做什么:

  1. 转换时间戳数字
  2. 找到最大值和最小值(如果不排序列表)
  3. 采取的区别最大值和最小值并将其转换回模式。

例如,在你的情况下,最大值和最小值之间的差值是43.而最小值已经是57,你可以很快地推断出如果最小值是*** 157,最大值应该是** * 200。你知道的模式

1

等于你几乎再也不想在生产中使用“*”参数Redis的,因为它是非常slow--比在绝大多数情况下单独为每个密钥请求要慢得多。除非你要求如此多的密钥以至于你的瓶颈变成了通过网络传输的大量数据(在这种情况下,你应该真的将其转换为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的答案。