如何在一个列表中分组以匹配python 3中其他字符串列表中的元素的字符串

如何在一个列表中分组以匹配python 3中其他字符串列表中的元素的字符串,python,python-3.x,Python,Python 3.x,我得到了744个图像文件,名称如下:“任务\代码\合作\日期1 \日期2 \ 01 \ T1/2 \ Bnumber.TIF”。如以下列表所示,例如: files = [ 'LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', #--¬ 'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF', #---note match except in the 'coord' part 'LT05_L1TP_0260

我得到了744个图像文件,名称如下:“任务\代码\合作\日期1 \日期2 \ 01 \ T1/2 \ Bnumber.TIF”。如以下列表所示,例如:

files = [
'LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', #--¬
'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF', #---note match except in the 'coord' part
'LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF',
'LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF',
'LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']
#---------^-----^
#         9    15
目标是将“任务代码”和“日期1\u日期2\u 01\u T1/2\u Bnumber.TIF”匹配的文件分组到子列表中,然后输出如下数组:

ord_files=[
    ['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF','LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF'],
    ['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF','LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'],
    ['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF','']]
有些文件有一对、三元组或单独存在。 我的想法是从一个新的列表(mo_文件)中的coord部分删除字符串,这样可以很容易地进行筛选,然后使用条件创建otput列表(ord_文件)

到目前为止,在这种情绪下,我尝试过以下方法:

for k in range(len(files)):
    mo_files[k][:] = files[k][9] + files[k][15]
只有我收到错误,如
索引器错误:列表索引超出范围
有一种更简单或更好的方法吗

谢谢。

您可以使用:

d = {} # you can also use collections.defaultdict

for f in files:
    d.setdefault(tuple(e for i, e in enumerate(f.split('_')) if i != 2), []).append(f)
list(d.values())
from collections import defaultdict

d = defaultdict(list) 
for f in files:
    d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)

list(d.values())
输出:

[['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF',
  'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF'],
 ['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF'],
 ['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'],
 ['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']]

或者您可以使用:

from collections import defaultdict

d = defaultdict(list) 
for f in files:
    d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)

list(d.values())
此版本的机器人速度更快

您可以使用:

d = {} # you can also use collections.defaultdict

for f in files:
    d.setdefault(tuple(e for i, e in enumerate(f.split('_')) if i != 2), []).append(f)
list(d.values())
from collections import defaultdict

d = defaultdict(list) 
for f in files:
    d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)

list(d.values())
输出:

[['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF',
  'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF'],
 ['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF'],
 ['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'],
 ['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']]

或者您可以使用:

from collections import defaultdict

d = defaultdict(list) 
for f in files:
    d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)

list(d.values())

如果您喜欢熊猫,则此版本的机器人速度更快

import pandas as pd
df = pd.DataFrame(files, columns=["filename"])                                                                                                                                 

# indeed define a "key" that is the whole string without 'coord' part
df["key"] = df.filename.apply(lambda s: s[:9]+s[16:])                                                 
现在,您所要做的就是
groupby
并使用
list
进行聚合:

>>> df.groupby("key").filename.apply(list).values                                                                                                                                  
array([list(['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']),
       list(['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', 'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF']),
       list(['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF']),
       list(['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'])],
      dtype=object)
顺便说一句,如果您不确定700多个文件中的索引是否会更改,那么更稳定的解决方案是使用
\uu
-拆分:

df["key"] = df.filename.apply(
    lambda filename: "_".join([part for idx, part in enumerate(filename.split("_")) if idx != 2])
)  

如果你喜欢熊猫:

import pandas as pd
df = pd.DataFrame(files, columns=["filename"])                                                                                                                                 

# indeed define a "key" that is the whole string without 'coord' part
df["key"] = df.filename.apply(lambda s: s[:9]+s[16:])                                                 
现在,您所要做的就是
groupby
并使用
list
进行聚合:

>>> df.groupby("key").filename.apply(list).values                                                                                                                                  
array([list(['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']),
       list(['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', 'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF']),
       list(['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF']),
       list(['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'])],
      dtype=object)
顺便说一句,如果您不确定700多个文件中的索引是否会更改,那么更稳定的解决方案是使用
\uu
-拆分:

df["key"] = df.filename.apply(
    lambda filename: "_".join([part for idx, part in enumerate(filename.split("_")) if idx != 2])
)  

我猜
mou文件[k]
是您的索引错误。您可能需要使用
mo\u files.append()
。不相关的,我建议写慢一点,而不是复杂的一行。例如,实现函数
get_mission
,该函数接收图像文件的名称并返回任务的名称。您的预期输出是错误的,因为在第二个列表中,date2是
20170106
20170107
@kederrac True!,第一次没有注意到,但修复了添加“和我!”4` . 谢谢。我猜
mou文件[k]
是您的索引错误。您可能需要使用
mo\u files.append()
。不相关的,我建议写慢一点,而不是复杂的一行。例如,实现函数
get_mission
,该函数接收图像文件的名称并返回任务的名称。您的预期输出是错误的,因为在第二个列表中,date2是
20170106
20170107
@kederrac True!,第一次没有注意到,但修复了添加“和我!”4` . 谢谢。优雅的回答。我想作者应该按照
mission\u code
date1\u date2\u 01\u T1/2\u Bnumber.TIF
进行分组。因此,
f.split(“”,1)[0]
似乎不是正确的键,但是
“”.join([part for idx,part in enumerate(filename.split(“”))如果idx!=2])
会这样做。你觉得怎么样?@Arnaud thx我已经更新了我的答案,我使用了
元组(e代表I,e在enumerate(f.split(“'))中,如果I!=2)
根据我的理解,除了
split
优雅的答案给出的第二个元素外,其余都是关键。我想作者应该按照
mission\u code
date1\u date2\u 01\u T1/2\u Bnumber.TIF
进行分组。因此,
f.split(“”,1)[0]
似乎不是正确的键,但是
“”.join([part for idx,part in enumerate(filename.split(“”))如果idx!=2])
会这样做。你觉得怎么样?@Arnaud thx我已经更新了我的答案,并且我使用了
元组(e代表I,e在枚举(f.split(“”))中,如果I!=2)
根据我的理解,除了
split