簡體   English   中英

篩選包含某些項目的元組的元組列表python

[英]Filter list of tuples for tuples that contain certain items python

我有一個像這樣的元組列表:

a = [('1', '2', '5', '5', 'w', 'w', 'w', 'w'),
     ('1', '3', '5', '5', 'w', 'w', 'w', 'w'),
     ('1', '3', '4', '5', 'w', 'w', 'w', 'w'),
     ('1', '4', '4', '4', 'w', 'w', 'w', 'w'),
     ('1', '5', '5', '5', 'w', 'w', 'w', 'w')]

我希望能夠過濾出包含某些項目的元組。 例如,我要查找所有包含'5', '5', 'w', 'w', 'w', 'w' ,並將它們放在列表中。

filter_for = ['5', '5', 'w', 'w', 'w', 'w']

預期結果將是:

result =  [('1', '2', '5', '5', 'w', 'w', 'w', 'w'),
           ('1', '3', '5', '5', 'w', 'w', 'w', 'w')]

filter_for長度將在1到7之間變化,因此我使用and不是理想的選擇。

我試過使用

[i for i in a if all(j in filtered_for for j in a)]

但這不起作用。

編輯:如果('1', '5', '5', '5', 'w', 'w', 'w', 'w')也位於列表中,我不希望該元組成為找到了。 我想我沒有指定這個,因為下面所有可行的解決方案也會返回這個元組。

如果我正確理解您的要求,這應該返回預期的結果。 在這里,我們列表轉換為字符串,並使用in檢查會員。

>>> a = [('1', '2', '5', '5', 'w', 'w', 'w', 'w'),
 ('1', '3', '5', '5', 'w', 'w', 'w', 'w'),
 ('1', '3', '4', '5', 'w', 'w', 'w', 'w'),
 ('1', '4', '4', '4', 'w', 'w', 'w', 'w')]
>>> filter_for = ''.join(['5', '5', 'w', 'w', 'w', 'w'])
>>> print [tup for tup in a if filter_for in ''.join(tup)]
[('1','2','5','5','w','w','w','w'), ('1','3','5','5','w','w','w','w')]

下面的代碼已更新,以匹配元組列表中的確切子列表。 不同於上面的示例中的模式匹配 ,我們在這里采用了截然不同的方法。

我們首先查找過濾器列表的headtail 然后,我們發現,其中的指數headtail發生在tup我們必須扭轉 tup 找到 tail_index ,由於 index 僅返回匹配的第一個元素 )。 然后,使用索引對,我們可以對該子列表進行切片以覆蓋headtail之間的距離。 如果此子列表過濾器匹配 ,那么我們知道搜索元組中存在該范圍。

def match_list(filter_list, l):
    results = []
    filter_for = tuple(filter_list)
    head = filter_for[0]
    tail = filter_for[-1]

    for tup in l:
        reverse_tup = tup[::-1]
        if head and tail in tup:
            try:
                head_index = tup.index(head)
                index_key = reverse_tup.index(tail)
                tail_index = -index_key if index_key else None
                if tup[head_index:tail_index] == filter_for:
                    results.append(tup)  # Prints out condition-satisfied tuples.
            except ValueError:
                continue
    return results

樣品輸出

 >>> a = [('1', '2', '5', '5', 'w', 'w', 'w', 'w'),
 ('1', '3', '5', '5', 'w', 'w', 'w', 'w'),
 ('1', '3', '4', '5', 'w', 'w', 'w', 'w'),
 ('1', '4', '4', '4', 'w', 'w', 'w', 'w'),
 ('1', '5', '5', '5', 'w', 'w', 'w', 'w')]  # <- Does not match!
 >>> filter_for = ['5', '5', 'w', 'w', 'w', 'w']
 >>> print match_list(filter_for, a)
 [('1','2','5','5','w','w','w','w'), ('1','3','5','5','w','w','w','w')]  

我不確定是否要指出您要嘗試的內容。 但我會按照以下方式進行操作:

>>>[i for i in a if "".join(filter_for) in "".join(i)]
[('1', '2', '5', '5', 'w', 'w', 'w', 'w'), ('1', '3', '5', '5', 'w', 'w', 'w', 'w')]

你是這個意思嗎

[i for i in a if all([j in i for j in filter_for])]

而不是你的線?

[i for i in a if all(j in filter_for for j in a)]

此代碼似乎有效,它通過將每個列表划分為與filter_for相同長度的幾個列表來測試每個列表

編輯編輯后,我嘗試添加一些排除的模式

a = [('1', '2', '5', '5', 'w', 'w', 'w', 'w'),
     ('1', '3', '5', '5', 'w', 'w', 'w', 'w'),
     ('1', '3', '4', '5', 'w', 'w', 'w', 'w'),
     ('1', '4', '4', '4', 'w', 'w', 'w', 'w'),
     ('1', '5', '5', '5', 'w', 'w', 'w', 'w')]

filter_for = ['5', '5', 'w', 'w', 'w', 'w']
excluded = [('1', '5', '5', '5', 'w', 'w', 'w', 'w')]

# add a padding key to excluded patterns
for x in range(len(excluded)):
    value = excluded[x]
    excl = {'value': value}

    for i in range(len(value) - len(filter_for) + 1):
        if list(value[i:i+len(filter_for)]) == list(filter_for):
            excl['padding'] = (i, len(value) - i - len(filter_for))

    excluded[x] = excl


def isexcluded(lst, i):
    # check if the lst is excluded by one of the `excluded` lists
    for excl in excluded:
        start_padding, end_padding = excl['padding']

        # get start and end indexes
        start = max(i-start_padding, 0)
        end = min(i + len(excl['value']) + end_padding, len(lst))

        if list(lst[start:end]) == list(excl['value']):
            return True

    return False


def get_lists(lists, length, excluded):
    for lst in lists:
        # get all the 'sublist', parts of the list that are of the same
        # length as filter_for
        for i in range(len(lst)-length+1):
            tests = [list(lst[i:i+length]) == list(filter_for),
                     not isexcluded(lst, i)]

            if all(tests):
                yield lst

result = list(get_lists(a, len(filter_for), excluded))

print(result)  # python 2: print result

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM