如何从计算的索引中显示循环列表

时间:2014-05-12 10:39:33

标签: python list circular-buffer

我有一个与

相似的词典列表
d = [{10: "a"}, {20: "b"}, {30: "c"}]

此列表按键排序。我不依赖于格式或数据类型 - 无论如何我都是从外部源构建这个列表(这就是说如果有帮助就可以更改它)

我还有一个变量x,范围从0100

我想要的是列表d重新排列(或重建或复制到其他地方),从大于x的第一个键开始。例如(编辑,抱歉,我在最初的例子中犯了一个错误)

  • 如果x == 2d = [{10: "a"}, {20: "b"}, {30: "c"}]
  • 如果x == 12d = [{20: "b"}, {30: "c"}, {10: "a"}]
  • 如果x == 22d = [{30: "c"}, {10: "a"}, {20: "b"}]
  • 如果x == 32d = [{10: "a"}, {20: "b"}, {30: "c"}]

我打电话给它"循环"因为它代表"下一个len(d)元素key > x"以封闭的方式。

我将以链式if的形式执行此操作,每次手动构建列表(上述示例涵盖了这些情况)。除了是一个糟糕的解决方案之外,如果len(d)变大,它就不是完全可扩展的(现在它是3,所以最糟糕的情况是我会选择链式if)。

处理此问题的pythonic解决方案是什么?

4 个答案:

答案 0 :(得分:1)

没有特别的原因,我想用一个列表理解来解决这个问题。这就是我想出的:

>>> from itertools import product
>>> d = [{10: "a"}, {20: "b"}, {30: "c"}]
>>> for x in (2, 12, 22, 32):
...     [e for i, e in product(range(2), d) 
...      if (0, x) < (i, next(iter(e))) <= (1, x)]
...
[{10: 'a'}, {20: 'b'}, {30: 'c'}]
[{20: 'b'}, {30: 'c'}, {10: 'a'}]
[{30: 'c'}, {10: 'a'}, {20: 'b'}]
[{10: 'a'}, {20: 'b'}, {30: 'c'}]

答案 1 :(得分:0)

我会使用切片和enumerate

for index, subdict in enumerate(d):
    if list(subdict)[0] > x:
        d = d[index:] + d[:index]
        break

是否有更好的数据结构满足您的需求?可能,但没有更多信息,很难确定它会是什么。正如您所说,所有子词典中的键在列表中是唯一的,您应该查看collections.OrderedDict - 您可以将所有数据放在同一个单一结构中。

答案 2 :(得分:0)

当x为22时,这首先给出30,因为30是第一个键&gt; 22:

d  = [{10: "a"}, {20: "b"}, {30: "c"}]
dd = d * 2 

for x in [2, 12, 22, 32, 42]:
    for i, h in enumerate(dd):
        k, v = h.items()[0]
        if k > x or i >= len(d): break
    print x, dd[i:i+len(d)]

输出:

2 [{10: 'a'}, {20: 'b'}, {30: 'c'}]
12 [{20: 'b'}, {30: 'c'}, {10: 'a'}]
22 [{30: 'c'}, {10: 'a'}, {20: 'b'}]
32 [{10: 'a'}, {20: 'b'}, {30: 'c'}]
42 [{10: 'a'}, {20: 'b'}, {30: 'c'}]

但是,由于列表已排序,您可以进行二进制搜索以提高性能。

答案 3 :(得分:0)

您可以使用以下内容,但这适用于简单的数据格式/类型。如果您的输入更复杂,那么您可能需要稍微调整一下。

d = [y for y in d if list(y)[0] > x] + [y for y in d if list(y)[0] <= x]