在列表中匹配并追加

时间:2019-02-06 16:03:02

标签: python

所以,我正在一个项目上,并且我有以下列表:

a = ['2 co',' 2 tr',' 2 pi', '2 ca', '3 co', '3 ca', '3 pi', '6 tr', '6 pi', '8 tr', '7 ca', '7 pi']

我想运行一个代码,该代码将检查每个字符串的第一个字符是否在另一个字符串中,并选择它们以将它们添加到新列表中。

我知道该怎么做,但仅适用于两个字符串。在这里,我想这样做,以便它将选择所有以相同字符串开头的字符串,并按其中的原始字符串数对其进行排序。例如,我想按3个字符串的子列表重新组合(因此,来自原始列表),所有可能以相同字符串开头的字符串组合。

此外,我希望结果仅对每个可能的子字符串关联计数一个字符串,而不会给出具有相同子字符串但顺序不同的不同组合。

在这种情况下(即当我想要3个子字符串并且带有a = ['2 co',' 2 tr',' 2 pi', '2 ca', '3 co', '3 ca', '3 pi', '6 tr', '6 pi', '8 tr', '7 ca', '7 pi']的字符串时)的预期结果是:

['2 co, 2 tr, ,2 pi', '2 co, 2 tr, 2, ca', '2pi, 2ca, 2tr',  '2pi, 2ca, 2co', 3 co, 3 ca, 3 pi]

您在这里看到,我没有'2 tr, 2 co, 2 pi',因为我已经有'2 co, 2 tr, ,2 pi'

当我想按4的子列表重新分组时,预期输出为

['2 co, 2 tr, 2, pi, 2 ca']

我设法做到了,但是只有在按两个的子集分组时,它才给出所有组合,包括一个具有相同子串但顺序不同的组合……

a = ['2 co',' 2 tr',' 2 pi', '2 ca', '3 co', '3 ca', '3 pi', '6 tr', '6 pi', '8 tr', '7 ca', '7 pi']
result = []
for i in range(len(a)):
    for j in a[:i]+a[i+1:]:
        if a[i][0] == j[0]:
            result.append(j)
print(result)

感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

您可以将itertools.groupbyitertools.combinations用于该任务:

import itertools as it
import operator as op

groups = it.groupby(sorted(a), key=op.itemgetter(0))
result = [', '.join(c) for g in groups for c in it.combinations(g[1], 3)]

请注意,如果元素的顺序仅取决于第一个字符,则可能需要向key=op.itemgetter(0)函数添加另一个sorted。如果数据已经预先排序,使得“相似”项(具有相同的第一个字符)彼此相邻,则可以将sorted放在一起。

详细信息

it.groupby根据数据的第一个字符(归因于key=op.itemgetter(0),该数据从每个字符串中选择第一个项目,即第一个字符)将数据分组。展开群组,如下所示:

[('2', ['2 co', '2 tr', '2 pi', '2 ca']),
 ('3', ['3 co', '3 ca', '3 pi']),
 ('6', ['6 tr', '6 pi']),
 ('7', ['7 ca', '7 pi']),
 ('8', ['8 tr'])]

然后为每个组it.combinations(..., 3)计算长度3的所有可能组合,并将它们合并为列表推导(对于少于3个成员的组,则不可能组合):

['2 co, 2 tr, 2 pi',
 '2 co, 2 tr, 2 ca',
 '2 co, 2 pi, 2 ca',
 '2 tr, 2 pi, 2 ca',
 '3 co, 3 ca, 3 pi']