Zip基于多对一关系列出在一起

时间:2015-08-11 03:36:23

标签: python

我有两个列表,我想通过压缩它们找到一种方法将它们链接在一起(我不确定这样做的确切术语)。

在列表一中,我有一系列tif文件:

    list1=['LT50300281984137PAC00_sr_band1.tif',
    ,'LT50300281984137PAC00_sr_band2.tif'  
    'LT50300281984137PAC00_sr_band3.tif','LT50300281994260XXX03_sr_band1.tif',
    'LT50300281994260XXX03_sr_band2.tif',
    'LT50300281994260XXX03_sr_band3.tif']
列表二中的

我有两个文件:

list2=[LT50300281984137PAC00_mask.tif,LT50300281994260XXX03_mask.tif]

我想将列表1中以LT50300281984137PAC00开头的文件压缩到列表2中的文件,该文件以相同的方式开头,对于以LT50300281994260XXX03开头的文件

我尝试的代码是:

ziplist=zip(sorted(list1),sorted(list2)

但这会返回:

[('LT50300281984137PAC00_sr_band1', 'LT50300281984137PAC00_mask.tif'), ('LT50300281984137PAC00_sr_band2', 'LT50300281994260XXX03_mask.tif')] 

我希望将其退回:

 [('LT50300281984137PAC00_sr_band1',LT50300281984137PAC00_sr_band2,LT50300281984137PAC00_sr_band3, 'LT50300281984137PAC00_mask.tif'), ('LT50300281994260XXX03_sr_band1.tif', 'LT50300281994260XXX03_sr_band2.tif','LT50300281994260XXX03_sr_band3.tif','LT50300281994260XXX03_mask.tif')] 

6 个答案:

答案 0 :(得分:3)

您可以使用itertools.groupby

stopService(new Intent(ActivityC.this, ServiceB.class));

结果:

from itertools import groupby

list1 = [
    'LT50300281984137PAC00_sr_band1.tif',
    'LT50300281984137PAC00_sr_band2.tif',
    'LT50300281984137PAC00_sr_band3.tif',
    'LT50300281994260XXX03_sr_band1.tif',
    'LT50300281994260XXX03_sr_band2.tif',
    'LT50300281994260XXX03_sr_band3.tif'
]

list2 = [
    'LT50300281984137PAC00_mask.tif',
    'LT50300281994260XXX03_mask.tif'
]

def extract_key(s):
    return s[:s.index('_')]

l = sorted(list1 + list2, key=extract_key)
l = [tuple(items) for s, items in groupby(l, key=extract_key)]

这个想法是按照每个文件名的第一部分([('LT50300281984137PAC00_sr_band1.tif', 'LT50300281984137PAC00_sr_band2.tif', 'LT50300281984137PAC00_sr_band3.tif', 'LT50300281984137PAC00_mask.tif'), ('LT50300281994260XXX03_sr_band1.tif', 'LT50300281994260XXX03_sr_band2.tif', 'LT50300281994260XXX03_sr_band3.tif', 'LT50300281994260XXX03_mask.tif')] )对两个列表的并集进行排序。然后使用extract_key创建相同第一部分的组。

答案 1 :(得分:1)

您可以使用列表推导和内置函数filter

In [24]: [tuple(filter(lambda x: x.startswith(e.split('_')[0]), list1)+[e]) for e in list2]
Out[24]:
[('LT50300281984137PAC00_sr_band1.tif',
  'LT50300281984137PAC00_sr_band2.tif',
  'LT50300281984137PAC00_sr_band3.tif',
  'LT50300281984137PAC00_mask.tif'),
 ('LT50300281994260XXX03_sr_band1.tif',
  'LT50300281994260XXX03_sr_band2.tif',
  'LT50300281994260XXX03_sr_band3.tif',
  'LT50300281994260XXX03_mask.tif')]

答案 2 :(得分:1)

也可以使用正则表达式完成。

import re
list1=['LT50300281984137PAC00_sr_band1.tif'
       ,'LT50300281984137PAC00_sr_band2.tif',  
       'LT50300281984137PAC00_sr_band3.tif','LT50300281994260XXX03_sr_band1.tif',
       'LT50300281994260XXX03_sr_band2.tif',
       'LT50300281994260XXX03_sr_band3.tif']

list2=['LT50300281984137PAC00_mask.tif','LT50300281994260XXX03_mask.tif']

match = re.findall(r'(\b\w+(?:PAC00)\w+.\w+\b)'," ".join(list1))
tuple1 =  tuple(match+[list2[0]])


match = re.findall(r'(\b\w+(?:0XXX0)\w+.\w+\b)'," ".join(list1))
tuple2 =  tuple(match+[list2[1]])

print [tuple1,tuple2]

输出

[('LT50300281984137PAC00_sr_band1.tif', 'LT50300281984137PAC00_sr_band2.tif', 'LT50300281984137PAC00_sr_band3.tif', 'LT50300281984137PAC00_mask.tif'), ('LT50300281994260XXX03_sr_band1.tif', 'LT50300281994260XXX03_sr_band2.tif', 'LT50300281994260XXX03_sr_band3.tif', 'LT50300281994260XXX03_mask.tif')]

答案 3 :(得分:0)

字典在这里可以更好地工作,然后您可以根据需要重新调整它:

password: {
    validators: {
        notEmpty: {
            message: 'The Password field is required.'
        },
        stringLength: {
            min: 5,
            max: 15,
            message: 'The Password must be more than 5 and less than 15 characters long'
        }

    }
} 

答案 4 :(得分:0)

我会使用itertools.chainitertools.groupby,并使用lambda表达式直到第一个_进行分组。示例 -

>>> from itertools import chain,groupby
>>> list1=['LT50300281984137PAC00_sr_band1.tif','LT50300281984137PAC00_sr_band2.tif','LT50300281984137PAC00_sr_band3.tif','LT50300281994260XXX03_sr_band1.tif','LT50300281994260XXX03_sr_band2.tif','LT50300281994260XXX03_sr_band3.tif']
>>> list2=['LT50300281984137PAC00_mask.tif','LT50300281994260XXX03_mask.tif']
>>>
>>> chained_sorted = sorted(chain(list1,list2))
>>> ret = []
>>> for i, x in groupby(chained_sorted,lambda x: x.split('_')[0]):
...     ret.append(tuple(x))
...
>>> ret
[('LT50300281984137PAC00_mask.tif', 'LT50300281984137PAC00_sr_band1.tif', 'LT50300281984137PAC00_sr_band2.tif', 'LT50300281984137PAC00_sr_band3.tif'), ('LT50300281994260XXX03_mask.tif', 'LT50300281994260XXX03_sr_band1.tif', 'LT50300281994260XXX03_sr_band2.tif', 'LT50300281994260XXX03_sr_band3.tif')]

答案 5 :(得分:0)

我在StackOverflow上的第一个答案,请耐心等待。但我没有看到需要zip()


mask1, mask2 = list2[0], list2[1]
for b in reversed(list1):
    if b[0:20] in mask1:
        mask1 = b + " " + mask1
    else:
        mask2 = b + " " + mask2

ziplist = [tuple(mask1.split()), tuple(mask2.split())]

我认为ziplist现在应该是你要求的了。