我在 python 中有一个由各种文件名组成的字符串列表,如下所示(但更长):
all_templates = ['fitting_file_expdisk_cutout-IMG-HSC-I-18115-6,3-OBJ-NEP175857.9+655841.2.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-3,3- OBJ-NEP180508.6+655617.3.feedme','fitting_file_sersic_cutout-IMG-HSC-I-18115-1,8-OBJ-NEP180840.8+665226.2.feedme','fitting_file_sersic_cutout-IMG-HSC-I-18115-6, 7-OBJ-NEP175927.6+664230.2.feedme'、'fitting_file_expdisk_cutout-IMG-HSC-I-18114-0,5-OBJ-zsel56238.feedme'、'fitting_file_devauc_cutout-IMG-HSC-I-18114-0,3- OBJ-NEP175616.1+660601.5.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-6,4-OBJ-zsel56238.feedme']
我想为具有相同对象名称的元素创建多个较小的列表(以 OBJ-
开头并在 .feedme
之前结束的子字符串)。所以我会有一个这样的列表:
obj1 = ['fitting_file_expdisk_cutout-IMG-HSC-I-18114-0,5-OBJ-zsel56238.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-6,4-OBJ-zsel56238。 feedme']
,
对于其他匹配的“对象”依此类推。实际上,我有超过 900 个独特的“对象”,原始列表 all_templates
有超过 4000 个元素,因为每个对象都有 3 个或更多单独的模板文件(它们都以随机顺序开始)。所以最后我想要超过 900 个列表(每个对象一个)。我怎样才能做到这一点?
编辑:这是我尝试过的,但它为我提供了每个子列表中所有原始模板文件名的列表(每个子列表对于一个对象名称都应该是唯一的)。
import re
# Break up list into multiple lists according to substring (object name)
obj_list = [re.search(r'.*(OBJ.+)\.feedme', filename)[1] for filename in all_template_files]
obj_list = list(set(obj_list)) # create list of unique objects (remove duplicates)
templates_objs_sorted = [[]]*len(obj_list)
for i in range(len(obj_list)):
for template in all_template_files:
if obj_list[i] in template:
templates_objs_sorted[i].append(template)
最佳答案
from collections import defaultdict
from pprint import pprint
all_templates = ['fitting_file_expdisk_cutout-IMG-HSC-I-18115-6,3-OBJ-NEP175857.9+655841.2.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-3,3-OBJ-NEP180508.6+655617.3.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-1,8-OBJ-NEP180840.8+665226.2.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-6,7-OBJ-NEP175927.6+664230.2.feedme', 'fitting_file_expdisk_cutout-IMG-HSC-I-18114-0,5-OBJ-zsel56238.feedme', 'fitting_file_devauc_cutout-IMG-HSC-I-18114-0,3-OBJ-NEP175616.1+660601.5.feedme', 'fitting_file_sersic_cutout-IMG-HSC-I-18115-6,4-OBJ-zsel56238.feedme']
# simple helper function to extract the common object name
# you could probably use Regex... but then you'd have 2 problems
def objectName(path):
start = path.index('-OBJ-')
stop = path.index('.feedme')
return path[(start + 5):stop]
# I really wanted to use a one line reduce here, but...
grouped = defaultdict(list)
for each in all_templates:
grouped[objectName(each)].append(each)
pprint(grouped)
旁白/切线
好吧,我无法使用reduce
做一个简单的衬里,这真的让我很烦恼。那里。最后祝愿python过得好groupby
功能。它具有同名的功能,但仅限于连续键。 Smalltalk、Objc 和 Swift 都有 groupby 机制,基本上允许您通过任意传输函数对 utterable 进行分桶。
我最初的尝试如下:
grouped = reduce(
lambda accum, each: accum[objectName(each)].append(each),
all_templates,
defaultdict(list))
问题出在 lambda 上。 lambda 仅限于单个表达式。为了让它在reduce中工作,它大多数会返回累积参数的修改版本。但是 python 不喜欢从函数/方法返回东西,除非必须这样做。即使我们更换了 append
与 <accessTheCurrentList> + [each]
,我们需要一个字典修改方法来更新键上的值并返回修改后的字典。我找不到这样的东西。
但是,我们可以做的是将更多信息加载到累加器中,例如元组。我们可以使用元组的一个槽来继续传递 defaultdict 指针,另一个槽来捕获修改操作的无用 None 返回。它最终变得相当丑陋,但它是一行:
from functools import reduce
grouped = reduce(
lambda accum, each: (accum[0], accum[0][objectName(each)].append(each)),
all_templates,
(defaultdict(list), None))[0]
关于python - 如何根据匹配的子字符串从一个列表创建多个列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54337537/