python中的itertools.groupby()

时间:2013-06-17 20:50:27

标签: python itertools

我有一组元组。例如:

set([(('E', ('T',)), 0),
 (('F', ('(', 'E', ')')), 0),
 (('T', ('F',)), 0),
 (('__S__', ('E', '$')), 0),
 (('E', ('E', '+', 'T')), 0),
 (('T', ('T', '*', 'F')), 0),
 (('F', ('id',)), 0)])

如你所见,每个元组都有一个元组,因为它是第一个元素(例如('F',('(','E',')')))。 这个元组的第一个元素是单个字符,第二个元素是另一个元组(例如('(','E',')')))。这个元组中有一个或多个单个字符。
(实际上是Context Free Grammar。第一个元素是规则(head)的LHS,第二个元素是RHS(body)
每个元组的第二个元素中的数字是指向该语法的RHS中的一个字符的指针。

我想要做的是将这个元组与已经指向的元素分组 为此,我写了以下代码:

import itertools
S = set([(('E', ('T',)), 0), (('F', ('(', 'E', ')')), 0), (('T', ('F',)), 0), (('__S__', ('E', '$')), 0), (('E', ('E', '+', 'T')), 0), (('T', ('T', '*', 'F')), 0), (('F', ('id',)), 0)])
for v, h in itertools.groupby(S, lambda x: x[0][1][x[1]] if len(x[0][1]) > x[1] else None ):
     if (v is None):
         continue
     print '--'
     print v
     for hi in h:
         print hi
如果x [0] [1] [x [1]]相同,则

两个元组属于同一组。 x [0] [1]是第一个元组的第二个元组(语法的RHS),x [1]是指针。
我得到以下结果:

--
(
(('F', ('(', 'E', ')')), 0)
--
F
(('T', ('F',)), 0)
--
E
(('__S__', ('E', '$')), 0)
--
T
(('T', ('T', '*', 'F')), 0)
--
id
(('F', ('id',)), 0)
--
T
(('E', ('T',)), 0)
--
E
(('E', ('E', '+', 'T')), 0)

正如您所看到的,有两个组带有键'T'。我不明白我在这里做错了什么!
我几乎是新的python程序员。如果问题太愚蠢了!
谢谢!

1 个答案:

答案 0 :(得分:3)

itertools.groupby()要求对数据进行排序,如果您希望对所有类似数据进行分组,请按照documentation

  

通常,迭代需要已经在同一个键上排序   功能

     

groupby()的操作类似于Unix中的uniq过滤器。它   每次键值产生一个中断或新组   功能变化(这就是为什么通常需要排序   数据使用相同的键功能)。这种行为不同于   SQL的GROUP BY聚合了常见元素而不管它们是什么   输入订单。

首先点击您的数据sorted()(使用您的功能作为关键功能),然后进行分组。

key_func = lambda x: x[0][1][x[1]] if len(x[0][1]) > x[1] else None
itertools.groupby(sorted(data, key=key_func), key_func)