使用字符串匹配模式将Python列表项分组

3
我需要像这样将相似的项目分组:

['bty_char_rick_10', 'shd_char_rick_10', 'refl_char_rick_10', 'spec_char_rick_10'], ['bty_char_toby_01', 'shd_char_toby_01'], ['bty_prop_item_01', 'shd_prop_item_01'] ...]

我在整个互联网上搜索了一遍,但找不到关于字符串操作的任何内容。应该是一个简单的fnmatch或字符串匹配,但我做不到。

from itertools import groupby

lst = ['bty_char_rick_10', 'bty_char_toby_01', 'bty_prop_chair_20', 'bty_prop_item_01', 'bty_prop_vase_10', 'bty_vhcl_tessla_10', 'occ_prop_vase_10', 'refl_char_rick_10', 'refl_prop_vase_10', 'shd_char_rick_10', 'shd_char_toby_01', 'shd_prop_chair_20', 'shd_prop_item_01', 'shd_prop_vase_10', 'shd_vhcl_tessla_10', 'spec_char_rick_10']

keyf = lambda text: text.split('_')[1]+'_'+text.split('_')[2]
print [list(items) for gr, items in groupby(sorted(lst), key=keyf)]
2个回答

4
你需要按相同的键对列表进行排序:
[list(g) for k, g in groupby(sorted(lst, key=f), key=f)]

f 表示:

f = lambda x: x.split('_')[1:]

示例:

from itertools import groupby

lst = ['bty_char_rick_10', 'bty_char_toby_01', 'bty_prop_chair_20', 'bty_prop_item_01',
       'bty_prop_vase_10', 'bty_vhcl_tessla_10', 'occ_prop_vase_10', 'refl_char_rick_10',
       'refl_prop_vase_10', 'shd_char_rick_10', 'shd_char_toby_01', 'shd_prop_chair_20',
       'shd_prop_item_01', 'shd_prop_vase_10', 'shd_vhcl_tessla_10', 'spec_char_rick_10']

f = lambda x: x.split('_')[1:]    
print([list(g) for k, g in groupby(sorted(lst, key=f), key=f)])

# [['bty_char_rick_10', 'refl_char_rick_10', 'shd_char_rick_10', 'spec_char_rick_10'],
#  ['bty_char_toby_01', 'shd_char_toby_01'],
#  ['bty_prop_chair_20', 'shd_prop_chair_20'],
#  ['bty_prop_item_01', 'shd_prop_item_01'],
#  ['bty_prop_vase_10', 'occ_prop_vase_10', 'refl_prop_vase_10', 'shd_prop_vase_10'],
#  ['bty_vhcl_tessla_10', 'shd_vhcl_tessla_10']]

0

你提出的解决方案由于排序而是 O(nlogn) 的。一个 O(n) 的解决方案只需要使用 collections.defaultdict

from collections import defaultdict

lst = ['bty_char_rick_10', 'bty_char_toby_01', 'bty_prop_chair_20', 'bty_prop_item_01',
       'bty_prop_vase_10', 'bty_vhcl_tessla_10', 'occ_prop_vase_10', 'refl_char_rick_10',
       'refl_prop_vase_10', 'shd_char_rick_10', 'shd_char_toby_01', 'shd_prop_chair_20',
       'shd_prop_item_01', 'shd_prop_vase_10', 'shd_vhcl_tessla_10', 'spec_char_rick_10']

d = defaultdict(list)
for string in lst:
    _, key = string.split("_", 1)
    d[key].append(string)

print(list(d.values()))

输出:

[['bty_char_rick_10', 'refl_char_rick_10', 'shd_char_rick_10', 'spec_char_rick_10'], ['bty_char_toby_01', 'shd_char_toby_01'], ['bty_prop_chair_20', 'shd_prop_chair_20'], ['bty_prop_item_01', 'shd_prop_item_01'], ['bty_prop_vase_10', 'occ_prop_vase_10', 'refl_prop_vase_10', 'shd_prop_vase_10'], ['bty_vhcl_tessla_10', 'shd_vhcl_tessla_10']]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接