2014-05-12 11 views
1

У меня есть список dicts подобногоКак отобразить циклический список из расчетного показателя

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

Этот список упорядочен по ключам. Я не привязан к формату или типу данных - я построю этот список из внешнего источника в любом случае (это означает, что она может быть изменена, если это помогает)

У меня также есть переменная x которая колеблется от 0 к 100 ,

Что бы я хотел получить, это список d перестроен (или перестроен или скопирован в другое место), начиная с первого ключа, большего чем x. Так, например (Edited, извините, я сделал ошибку в исходном примере)

  • , если 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).

Что было бы питоническим решением для этого?

+1

У всех словарей есть один ключ? Считаете ли вы использование 'OrderedDict' или список кортежей? – jonrsharpe

+0

Да, у них есть единственный и уникальный ключ. Я не рассматривал 'OrderedDict' или список кортежей, но я могу изменить тип данных на все, что удобно для решения, отличного от my' if's. – WoJ

+0

Все ключи в словаре уникальны, это был факт, что меня только удивил. Для определения наилучшей структуры данных потребуется гораздо больше информации. Ваши примеры не соответствуют описанию *, начиная с первого ключа, большего, чем 'x' * *. – jonrsharpe

ответ

0

Я хотел бы использовать нарезку и enumerate:

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

Есть ли лучшая структура данных для ваших нужд? Наверное, но без дополнительной информации трудно определить, что это будет. Как вы говорите, ключи во всех ваших суб-словарях уникальны в списке, вы должны посмотреть в collections.OrderedDict - вы могли бы иметь все данные в одной и той же структуре.

0

Это дает 30 первых, когда х 22, поскольку 30 является первым ключом> 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'}] 

Но поскольку список сортируется вы можете сделать бинарный поиск для повышения производительности.

+0

Спасибо - я понял (также благодаря комментарию jonrsharpe), что я допустил ошибку в своих примерах – WoJ

0

Вы можете использовать следующее, однако это работает для простых форматов и типов данных. Если ваши входы более сложны, вам, возможно, придется немного подкорректировать их.

d = [y for y in d if list(y)[0] > x] + [y for y in d if list(y)[0] <= x] 
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'}] 

 Смежные вопросы

  • Нет связанных вопросов^_^