2

潜在的に長さが異なる 2 つのリストがあります。各リストには、文字列形式のファイル名が含まれています。名前を制御することはできませんが、名前の構造は変更されないことを確信しています。常に name1_name2_number1_+(or-)number2.jpg のようなものになります

Number1 は、2 つのリスト間で一致させたい部分文字列です。1 つのリストのファイル名に他のリストのファイル名と同じ number1 が含まれている場合、これらのファイル名の両方を 3 番目のリストに追加します。特定のリストでnumber1を取得する単純な関数があります。たとえば、次のとおりです。

>>>list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']
>>>def GetNum(imgStrings):
...    ss = []
...    for b in imgStrings:
...        ss.append([w for w in b.split('_') if w.isdigit()])
...    #flatten zee list of lists because it is ugly.
...    return [val for subl in ss for val in subl]
>>>GetNum(list1)
['200', '800]

だから、

>>>list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']
>>>list2 = ['inara03_summer40_8000_-2.jpg', 'book23_42jayne_400_+2.jpg', 'summer53_21simon_300_-1.jpg']
>>>awesomesauceSubstringMatcher(list1, list2)
['inara03_kaley40_8000_-1.jpg', 'inara03_summer40_8000_-2.jpg']

GetNum関数といくつかのリスト内包表記でそれを行うことができるはずだと感じていますが、「[何とか何とか…]」構文全体である気の利いたものは私にとって新しいものであり、私のものを完全にラップすることはできませんこれを回ってください。考え?提案?死の脅迫?事前のすべての有益な回答に感謝します。また、私のgooglefuが同様の質問/回答を見つけようとして失敗した場合は、何千もの謝罪をします。

編集 私はこの解決策を見つけました:

[str for str in list1+list2 if any(subs in str for subs in GetNum(list1)) and any(subs in str for subs in GetNum(list2))]

長くて醜いことはわかっていますが、リスト内包表記でそれができることを自分自身に証明したかったのです。役立つ回答をありがとうございます。

4

6 に答える 6

2
list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']
list2 = ['inara03_summer40_8000_-2.jpg', 'book23_42jayne_400_+2.jpg', 'summer53_21simon_300_-1.jpg']

def getNum(image_name_list):
    for s in image_name_list:
        s = s.split('_')[2]
        if s.isdigit():
           yield s        
        else:
            yield None

def getMatchingIndex(list1, list2):
    other_list = list(getNum(list2))
    for (i, num) in enumerate(getNum(list1)):
        if not num:
            continue
        for (j, other_num) in enumerate(getNum(list2)):
            if (num == other_num):
                yield (i, j)

for i1, i2 in getMatchingIndex(list1, list2):
    print list1[i1], list2[i2]

一度に 1 つの項目を 2 番目のリストのすべての時間と比較するだけでよいため、メモリを節約するために getNum でジェネレーターを使用しました。番号が複数回一致する可能性があるため、各項目をチェックし続けます。

于 2013-03-15T18:56:43.463 に答える
0

テストされていませんが、ロジックは正しいはずです:

list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']
list2 = ['inara03_summer40_8000_-2.jpg', 'book23_42jayne_400_+2.jpg', 'summer53_21simon_300_-1.jpg']
list3 = []

seenInList1Dict = {}

for element in list1:
    splitelem = element.split('_')
    seenInList1Dict[splitelem[2]] = 1

for element in list2:
    splitelem = element.split('_')
    if splitelem[2] in seenInList1Dict:
        list3.append(element)

GetNumIMO を不必要に複雑にするため、使用しませんでした。後でそれらの存在をすばやく見つけて比較したい場合は、物事を辞書にダンプする方が簡単だと思います。また、番号が必要な場合はsplit、ファイル名に対して a を実行し、適切なインデックスから必要な値を取得するだけです。

于 2013-03-15T18:56:31.793 に答える
0

キーがファイル名からの番号で、値がファイル名自体である両方のリストの辞書を作成します。次に、キーの 2 つのセットを「交差」させます。結果の共通キーを使用して、3 番目のリストを作成できます。たとえば、次のようになります。

def List2Dic(List):
    return dict(map(lambda x: [ x.split("_")[2], x], List))

list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']
list2 = ['inara03_summer40_8000_-2.jpg', 'book23_42jayne_400_+2.jpg', 'summer53_21simon_300_-1.jpg']

d1 = List2Dic(list1)
d2 = List2Dic(list2)

for x in set(d1) & set(d2):
    print d1[x], d2[x]
于 2013-03-15T19:08:35.410 に答える
0
My bit of the solution using map,reduce, filter and list flattening using sum:-
l=['a_b_1_2','b_c_2_3']
s=['c_d_3_4','d_e_1_4']
a=map(lambda y: map(lambda z:  [y,z] if y[2] == z[2] else '', map(lambda v:v.split('_'), s)),map(lambda x:x.split('_'),l))

map(lambda x: '_'.join(x), sum(filter(lambda qq: qq is not '',sum(a,[]))))

実際のデータセットで表示する:

>>> list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']    
>>> list2 = ['inara03_summer40_8000_-2.jpg', 'book23_42jayne_400_+2.jpg', 'summer53_21simon_300_-1.jpg']

>>> a=map(lambda y: map(lambda z:  [y,z] if y[2] == z[2] else '', map(lambda v:v.split('_'), list2)),map(lambda x:x.split('_'),list1))

>>> a 

    [['', '', ''], [[['inara03', 'kaley40', '8000', '-1.jpg'], ['inara03', 'summer40', '8000', '-2.jpg']], '', '']]


>>> sum(filter(lambda qq: qq is not '',sum(a,[])),[])

    [['inara03', 'kaley40', '8000', '-1.jpg'], ['inara03', 'summer40', '8000', '-2.jpg']]

>>> map(lambda x: '_'.join(x), sum(filter(lambda qq: qq is not '',sum(a,[])),[]))

    ['inara03_kaley40_8000_-1.jpg', 'inara03_summer40_8000_-2.jpg'] #This is the output you want.
于 2013-03-15T19:22:41.550 に答える
0

文字列を解析して、実際にふるいにかけることができるデータにします。その後、物事ははるかに簡単になります。

def process(filename):
    splitup = filename.rstrip('.jpg').split('_')
    keys = ["name1", "name2", "number1", "number2"]
    r = dict(zip(keys, splitup))
    r["filename"] = filename
    return r

list1 = ['serentity01_20malcolm_200_+3.jpg','inara03_kaley40_8000_-1.jpg']
list2 = ['inara03_summer40_8000_-2.jpg', 'book23_42jayne_400_+2.jpg', 'summer53_21simon_300_-1.jpg']

plist1 = [process(f) for f in list1]
plist2 = [process(f) for f in list2]

nlist1 = [i['number1'] for i in plist1]
nlist2 = [i['number1'] for i in plist2]

ilist1 = [i for i in plist1 if i['number1'] in nlist2]
ilist2 = [i for i in plist2 if i['number1'] in nlist1]

intersection = set([i["filename"] for i in ilist1 + ilist2])

for i in intersection:
    print i

編集:シュート、両方のリストからの交差点が必要なことがわかりました。

于 2013-03-15T19:09:29.357 に答える