Ich habe zwei Listen und möchte einen Weg finden, sie miteinander zu verknüpfen (ich bin mir nicht sicher, wie genau dies bezeichnet wird), indem ich sie komprimiere.

In Liste eins habe ich eine Reihe von TIF-Dateien:

    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']

In Liste zwei habe ich zwei Dateien:

list2=[LT50300281984137PAC00_mask.tif,LT50300281994260XXX03_mask.tif]

Ich möchte die Dateien in Liste 1, die mit LT50300281984137PAC00 beginnen, in die Datei in Liste 2 komprimieren, die auf die gleiche Weise beginnt, und für die Dateien, die mit LT50300281994260XXX03 beginnen.

Der Code, den ich versucht habe, ist:

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

Aber das kehrt zurück:

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

Ich möchte, dass dies zurückgegeben wird:

 [('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')] 
3
Stefano Potter 11 Aug. 2015 im 06:36

6 Antworten

Beste Antwort

Sie können itertools.groupby verwenden:

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)]

Ergebnis:

[('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')]

Die Idee ist, die Vereinigung der beiden Listen nach dem ersten Teil jedes Dateinamens (extract_key) zu sortieren. Verwenden Sie dann groupby, um Gruppen desselben ersten Teils zu erstellen.

3
JuniorCompressor 11 Aug. 2015 im 03:50

Meine erste Antwort auf StackOverflow, bitte haben Sie etwas Geduld. Aber ich sah keine Notwendigkeit für 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())]

Ich denke, Ziplist sollte jetzt das sein, wonach Sie gefragt haben.

0
David S Jackson 11 Aug. 2015 im 17:11

Ich würde itertools.chain und itertools.groupby mit einem Lambda-Ausdruck verwenden, um nur bis zum ersten _ für die Gruppierung zu verwenden. Beispiel -

>>> 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')]
0
Anand S Kumar 11 Aug. 2015 im 03:53

Ein Wörterbuch funktioniert hier besser. Sie können es später für das verwenden, was Sie benötigen:

results = {}

for f in list2:
    common = f.split('_')[0]
    results[common] = []

for f in list1:
    common = f.split('_')[0]
    try:
        results[common].append(f)
    except KeyError:
        print('{} not a valid grouper'.format(common))

# To convert into a list of tuples
as_list = [(k,)+tuple(v) for k,v in results.iteritems()]
print(as_list)
0
Burhan Khalid 11 Aug. 2015 im 03:50

Kann auch mit Regex durchgeführt werden.

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]

Ausgabe

[('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')]
1
Vineet Kumar Doshi 11 Aug. 2015 im 03:57

Sie können das Listenverständnis und die integrierte Funktion filter verwenden.

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')]
1
Alik 11 Aug. 2015 im 03:49