Как отсканировать список на частичное появление с помощью словаря? - PullRequest
0 голосов
/ 03 марта 2019

Я пытаюсь использовать словарь для сканирования списка строк, чтобы увидеть, появляется ли он вообще в строке, например, допустим, у меня есть словарь {'C99': 1, 'C4': 1} ссписок ['C99C2C3C5', 'C88C4'], тогда новый список будет ['1', '1'], потому что в строке «C99C2C3C4» отображается «C99», а в «C88C4» - «C4».

Мой текущий способ сделать это:

import re

dict = {'C99': 1,'C15':1}
ComponentList = ['C1C15C99', 'C15', 'C17']

def func(s):
    for k, v in dict.items():
        if all(i in s for i in re.findall('\w\d', k)):
            return v
    else:
        return 0

ComponentList = [func(i) for i in ComponentList]

Вывод:

[1, 1, 1]

Требуемый вывод:

[1,1,0]

Для уточнения, если этомоя система:

my_dict = {'C1C55C99': 1, 'C17': 1, 'C3': 1}
component_list = ['C1C15C55C99', 'C15', 'C17']

Поскольку 'C1C55C99' появляется в пределах 'C1C15C55C99', я бы хотел, чтобы значение изменилось на значение словаря, чтобы выдать вывод:

results = ['1','0','1']

Однако этоМетод не работает, когда номер компонента становится выше C9, и я надеюсь, что кто-то может помочь мне в исправлении, поэтому он может работать для Cx и объяснить, почему предыдущий метод не работал.

Спасибо, Бен

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

Основываясь на изменениях в вашем вопросе и комментариях, я думаю, что (наконец) понимаю, что вы хотите сделать, поэтому вот мой существенно пересмотренный ответ.

Я думаю, что показанный код может немного улучшить / оптимизировать, но сначала хотелось бы получить подтверждение того, что теперь он работает правильно.

import re

def func(comps):
    pats = [c for c in re.findall(r'\w\d+', comps)]

    for k, v in my_dict.items():
        if any(p in k for p in pats):
            return v

    return 0

# Testcases

my_dict = {'C99': 1, 'C4': 1}
components_list =  ['C99C2C3C5', 'C88C4']
result = [func(comps) for comps in components_list]
print('result:', result)  # -> result: [1, 1]

my_dict = {'C99': 1,'C15': 1}
components_list = ['C1C15C99', 'C15', 'C17']
result = [func(comps) for comps in components_list]
print('result:', result)  # -> result: [1, 1, 0]

my_dict = {'C1C55C99': 1, 'C17': 1, 'C3': 1}
components_list = ['C1C15C55C99', 'C15', 'C17']
result = [func(comps) for comps in components_list]
print('result:', result)  # -> result: [1, 0, 1]

Примечание : Вына самом деле не следует называть переменные так же, как встроенные в Python, например dict, так как это сбивает с толку и может привести к незначительным ошибкам, если вы не очень осторожны (или вам просто не повезло).

Как правило, я бы рекомендовал следовать PEP 8 - Руководству по стилю для кода Python , особенно разделу Соглашения об именах , в котором также потребуется изменить ComponentList на строчные словаразделенные "_" символами - в этом случае components_list будет соответствовать рекомендациям.

0 голосов
/ 03 марта 2019

Из ваших комментариев здесь, мне кажется, что символ 'C' в вашем списке компонентов важен, потому что вы, кажется, хотите различать, например, 'C11' и 'C1'.

Кстати,Я полностью согласен с @martineau, чтобы всегда использовать стандартное именование в Python.CamleCasingLikeThis должен быть зарезервирован только для имен классов, и вы должны использовать lower_case_like_this для переменных в целом, без заглавных букв.

Давайте рассмотрим, как это можно сделать.

my_dict = {'C99': 1, 'C15': 1, 'C1': 1}
component_list = ['C1C15C99', 'C15', 'C17']

result = []

# first convert my_dict to a list of numbers ['99', '15', '1']
elements = [element[1:] for element in my_dict.keys()]

# for every component you want to characterize
for component in component_list:

    # a flag to know if we found any element in this component
    found = False

    # split the string by the 'C' character to get its sub element numbers
    # for example 'C1C15C99'.split('C') == ['', '1', '15', '99']
    for sub_elem in component.split('C'):

        # make sure sub_elem is not an empty string
        if sub_elem:

            # check if this sub element exists in elements
            if sub_elem in elements:

                found = True

                # exit the inner loop
                break

    # convert the boolean to int (either 0 or 1)
    # and finally add this to the result
    result.append(int(found))

print(result)
# [1, 1, 0]

До сих пор я предполагал, что my_dict может принимать только отдельные компоненты, такие как C1 или C6но не такие композиты, как C12C14.Из вашего последнего комментария кажется, что это не так.Внезапно выясняются еще две вещи: my_dict может содержать комбинацию компонентов, и при проверке наличия одного в другом порядок не имеет значения.Например, C1C2 существует в C5C2C7C1, но C1C2 не существует в C1, поскольку должны присутствовать оба подкомпонента.

Это очень важно и полностью меняет проблему.Для дальнейшего использования, пожалуйста, не забудьте подробно описать вашу проблему с самого начала.

my_dict = {'C99': 1, 'C15': 1, 'C1': 1, 'C1C55C99': 1, 'C99C6': 1, 'C2C4C18': 1}
component_list = ['C1C15C99', 'C15', 'C17', 'C8C6C80C99', 'C6', 'C55C2C4C18C7', 'C55C1', 'C18C4']

result = []

# first convert my_dict to a list of lists containing singular elements
elements = [element.split('C')[1:] for element in my_dict.keys()]
# elements = [['2', '4', '18'], ['99'], ['1'], ['15'], ['99', '6'], ['1', '55', '99']]

for component in component_list:

    found = False

    # gather the sub elements for this components
    comp_elements = component.split('C')[1:]

    for composite_element in elements:

        element_exists = True

        # check if every singular element in this element is present in component
        for signular_element in composite_element:

            if signular_element not in comp_elements:
                element_exists = False
                break

        if element_exists:
            found = True
            break

    result.append(int(found))

print(result)
# [1, 1, 0, 1, 0, 1, 1, 0]
0 голосов
/ 03 марта 2019

Я плохо разбираюсь в одном, но это намного проще, чем у вас, и не нужно было использовать регулярные выражения, просто используйте if x in y

def func(s):
for k, v in dict.items():
    if k in s:
        return v
return 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...