Эффективно находите совпадающие индексы и значения для вложенного списка кортежей - PullRequest
0 голосов
/ 10 июля 2020

Я работаю со списками разных размеров, и мой вопрос:

Предположим, у меня есть два списка кортежей с разными размерами:

value1 = [(0, 1), (0, 2), (0, 3)]
value2 = [(0, 6), (0, 2), (0, 4), (0, 9), (0, 7)]

Вставлено в другой список:

my_list = [value1, value2]

Каков наиболее эффективный способ ( предпочтительно O (n) ) найти соответствующий индекс при добавлении mylist с third list и затем возврата по порядку? Результат должен выглядеть примерно так:

value3 = [(0, 1), (0, 2), (0, 3), (0, 5), (0, 7), (0, 10)]

mathing_values (my_list, value3): 
    
    my_list.append(value3)

    return ->  "The List 'value3' has a matching with 'value1' in 
                index 0 : (0, 1), index 1: (0, 2) and with 'value2'
                in index 4: (0, 7)"

Obs: Если это работает для нескольких списков (более 3), было бы идеально

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Я не уверен, что это наиболее эффективный способ, но читабельный и простой:

v3 = set(value3)

[set(x).intersection(v3) for x in my_list]

UPD: расширенное решение с указателями, использующими значение dict в качестве индекса:

v3 = set(value3)

[(i, k) for x in my_list for (i, k) in enumerate(set(x)) if k in v3]
0 голосов
/ 10 июля 2020

Я не думаю, что set() сработает, так как вам нужны индексы, поэтому это не очень эффективно, но оно будет работать:

def find_matches(my_list, new_list):
    indices = []
    values = []
    for index, (a, b) in enumerate(zip(my_list[0], my_list[1])):
        for new_value in new_list:
            if new_value == a or new_value == b:
                indices.append(index)
                values.append(new_value)
    if len(indices) == 0:
        return "No matches"
    else:
        return "Matching Values: {} Corresponding Indices: {}".format(values, indices)

Затем просто вызовите функцию:

print(find_matches(my_list, value3))

вывод:

Соответствующие значения: [(0, 1), (0, 2), (0, 3)] Соответствующие индексы: [0, 1, 2]

Вот решение с pandas, которое будет намного быстрее и может включать столько списков, сколько вы хотите. Надеюсь, это поможет.

import pandas as pd

def find_matches(my_list, new_list):
    
    #create a dataframe from the lists contained in my_list
    dfs = []
    for l in my_list:
        l_series = pd.Series(l)
        l_df = pd.DataFrame(l_series)
        dfs.append(l_df)
    df = pd.concat(dfs, ignore_index=True, axis=1)
    
    #create second df of Boolean values if there are matches to the new_list
    df2 = df[df.isin(new_list)]
    df_final = df2.dropna(how='all')#drop rows where no matches were found in any list

    
    return df_final

звонок:

find_matches(my_list, value3)

Возврат:

    0   1
0   (0, 1)  NaN
1   (0, 2)  (0, 2)
2   (0, 3)  NaN
4   NaN (0, 7)
...