我有一个与
相似的词典列表d = [{10: "a"}, {20: "b"}, {30: "c"}]
此列表按键排序。我不依赖于格式或数据类型 - 无论如何我都是从外部源构建这个列表(这就是说如果有帮助就可以更改它)
我还有一个变量x
,范围从0
到100
。
我想要的是列表d
重新排列(或重建或复制到其他地方),从大于x
的第一个键开始。例如(编辑,抱歉,我在最初的例子中犯了一个错误)
x == 2
则d = [{10: "a"}, {20: "b"}, {30: "c"}]
x == 12
则d = [{20: "b"}, {30: "c"}, {10: "a"}]
x == 22
则d = [{30: "c"}, {10: "a"}, {20: "b"}]
x == 32
则d = [{10: "a"}, {20: "b"}, {30: "c"}]
我打电话给它"循环"因为它代表"下一个len(d)
元素key > x
"以封闭的方式。
我将以链式if
的形式执行此操作,每次手动构建列表(上述示例涵盖了这些情况)。除了是一个糟糕的解决方案之外,如果len(d)
变大,它就不是完全可扩展的(现在它是3
,所以最糟糕的情况是我会选择链式if
)。
处理此问题的pythonic解决方案是什么?
答案 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]