Как я могу перефакторизовать эту функцию кругового раскроя словаря? - PullRequest
0 голосов
/ 11 февраля 2020

Задача:

Недавно я получил извлечение данных со списком имен папок и связанных подпапок. Задача состояла в том, чтобы создать повторно используемую функцию, которая могла бы предоставлять сводку уникальных имен папок и всех вложенных подпапок.

Источником данных была электронная таблица Excel, содержащая 2 столбца:

Parent: Folder имя

дочерний элемент: имя подпапки

Примечание. Я заново создал данные электронной таблицы, используя pandas, чтобы можно было легко проверить код.

Создать таблицу :

import pandas as pd

data = {'Parent': ['A', 'B', 'C', 'D', 'E', 'F', 'C', 'C'],
        'Child': ['B', 'C', 'E', 'E', 'Z', 'Z', 'B', 'A']}

df = pd.DataFrame(data)

print(df):

Parent  Child
0   A   B
1   B   C
2   C   E
3   D   E
4   E   Z
5   F   Z
6   C   B
7   C   A

Мое решение:

def relationship_dictionary(dataframe, key_column_name, values_column_name):
    """
    The key_column_name is the primary data source that should be considered the 
    start of the nested relationship.

    The values_column_name is the subfolder

    Creates a dictionary of unique relationships to each key.
    """

    parent = key_column_name
    child = values_column_name
​
    d = {}
    for i, row in dataframe.iterrows():
        key = row[parent]
        value = row[child]
        if key in d.keys():
            d[key].append(value)
        else:
            d[key] = [value]

    for k, values in d.items():
        for v in values:
            if v in d.keys():
                for each in d[v]:
                    if (each not in d[k]) and (each != k):
                        d[k].extend([each])
    return d

Результат:

relationship_dictionary(df, "Parent", "Child")
{'A': ['B', 'C', 'E', 'Z'],
 'B': ['C', 'E', 'A', 'Z'],
 'C': ['E', 'B', 'A', 'Z'],
 'D': ['E', 'Z'],
 'E': ['Z'],
 'F': ['Z']}

Обратная связь

Я счастлив сказать, что это работает после смягчения проблемы циклического вложения, но я не могу не думать, что есть гораздо более простой способ сделать это, поэтому я подумал, что выложу это для критики, поэтому обратная связь будет приветствоваться ...:)

...