0

我有一个来自数据库的操作列表。这被复制到一个双端队列中,因为我想按顺序处理它,一边走一边从左边弹出东西。

所以我有类似 actions = deque(actions) 的东西,这很好。

每个操作项都是来自使用 DictCursor 的 psycopg 模块的列表。每个列表都有项目“阶段”。

所以事情是分阶段进行的。有些动作在“a”阶段,有些在“b”阶段,等等。这不是存储数据的最佳方式,但这就是我得到的。

所以为了让我的生活更轻松,我想将双端队列分阶段分成几个双端队列。

因此,如果 actions[0]['phase'] == 'a' 那么这将进入一个列表,其中仅包含来自阶段 a 的项目,依此类推,b 等。

我可以通过一堆 if 和附加来做到这一点,但这似乎需要付出很多努力。我认为答案可能是 filter(),但我不太确定如何使用它。

随机注意事项:

  • 每个项目都是有序的,需要在每个双端队列中保留顺序。
  • 这些阶段是已知的和连续的。例如,如果阶段 c 不存在,我们知道阶段 d 不存在。阶段的数量是有限的,如果我记得的话,大概是 5 个。

澄清尝试:

我有一个双端队列,动作。就像是:

actions = [
    ['phase': 'a', 'something_else': 'x'], 
    ['phase': 'a', 'something_else': 'y'],
    ['phase': 'b', 'something_else': 'x']
]

想要结束(类似):

a = [
    ['phase': 'a', 'something_else': 'x'], 
    ['phase': 'a', 'something_else': 'y']
]
b = [
    ['phase': 'b', 'something_else': 'x']
]

使用最少的代码,以及适用于阶段/等中任意数量的阶段/项目的东西。

4

2 回答 2

2

首先定义一个键函数,当给定一个动作时返回相位,例如

key = lambda action: action["phase"]

现在首先排序key——这不会重新排列不必要的顺序,即每个阶段都保持顺序(它是“稳定的”)——然后像这样使用groupbyfrom itertools

from itertools import groupby

actions.sort(key=key)

results = []    
for phase, action_iterable in groupby(actions, key=key):
    action_list = list(action_iterable)
    action_list.reverse()
    results.append((phase, action_list)))

如您所见,我已经颠倒了列表。这样您就可以有效地弹出列表的末尾,而不是在双端队列上使用 popleft。如果您愿意,可以将它们变成双端队列而不是反转。现在像这样使用:

for phase, actions in results:
    while actions:
        action = actions.pop()
        # etc...
于 2012-06-11T13:45:17.010 回答
0

我认为您需要 itertools 模块中的 groupby 。

http://docs.python.org/library/itertools.html#itertools.groupby

于 2012-06-11T13:43:33.500 回答