我有一个列表:
["asdf-1-bhd","uuu-2-ggg","asdf-2-bhd","uuu-1-ggg","asdf-3-bhd"]
我想在删除号码后拆分成两个元素相等的组:
"asdf-1-bhd", "asdf-2-bhd", "asdf-3-bhd"
"uuu-2-ggg" , uuu-1-ggg"
我一直在使用itertools.groupby
和
for key, group in itertools.groupby(elements, key= lambda x : removeIndexNumber(x)):
但是当要分组的元素不连续时,这不起作用。
我考虑过使用列表推导,但这似乎是不可能的,因为组的数量不固定。
TL; DR:
我想分组,两个问题:
答案 0 :(得分:3)
你为什么不考虑它有点不同。您可以将每个地图映射到一个字典:
import re
from collections import defaultdict
regex = re.compile('([a-z]+\-)\d(\-[a-z]+)')
t = ["asdf-1-bhd","uuu-2-ggg","asdf-2-bhd","uuu-1-ggg","asdf-3-bhd"]
maps = defaultdict(list)
for x in t:
parts = regex.match(x).groups()
maps[parts[0]+parts[1]].append(x)
输出:
[['asdf-1-bhd', 'asdf-2-bhd', 'asdf-3-bhd'], ['uuu-2-ggg', 'uuu-1-ggg']]
这非常快,因为您不必将一件事与另一件事进行比较。
编辑:
以不同的方式思考
您最初的方法是迭代每个项目并将它们相互比较。这是过于复杂和不必要的。
让我们考虑一下我的代码。首先它得到了精简版:
"asdf-1-bhd" -> "asdf--bhd"
"uuu-2-ggg" -> "uuu--ggg"
"asdf-2-bhd" -> "asdf--bhd"
"uuu-1-ggg" -> "uuu--ggg"
"asdf-3-bhd" -> "asdf--bhd"
您已经可以开始查看群组了,我们还没有比较任何内容!
我们现在进行一种反向映射。我们把所有东西都放在右边,把它作为一个键,左边的任何东西放在一个列表中,该列表由左边的值映射:
'asdf--bhd' -> ['asdf-1-bhd', 'asdf-2-bhd', 'asdf-3-bhd']
'uuu--ggg' -> ['uuu-2-ggg', 'uuu-1-ggg']
我们的组由他们的公共计算值(键)定义。这适用于任何数量的元素和组。
答案 1 :(得分:0)
好的,简单的解决方案(这里一定为时已晚):
使用itertools.groupby
,但首先sort
列表。
至于上面给出的例子:
elements = ["asdf-1-bhd","uuu-2-ggg","asdf-2-bhd","uuu-1-ggg","asdf-3-bhd"]
elemens.sort(key = lambda x : removeIndex(x))
for key, group in itertools.groupby(elements, key= lambda x : removeIndexNumber(x)):
for element in group:
# do stuff
如您所见,排序条件与分组相同。这样,最终必须分组的元素首先被置于连续的顺序中。完成此操作后,itertools.groupy
可以正常运行。