Pythonic способы изменить элементы, которые содержат определенное количество (не только символы) в списке - PullRequest
0 голосов
/ 04 декабря 2018

Я пишу функцию 'упрощение', чтобы упростить полиномы, чтобы simplify("2xy-yx") мог вернуть "xy", simplify("-a+5ab+3a-c-2a") может вернуть "-c+5ab" и т. Д.

Я нахожусь на стадии, гдеЯ объединил те же самые мономы, но некоторые мономы будут иметь коэффициент +1 или -1.Я хочу изменить их на + или -.Но я просто не могу просто удалить 1, иначе коэффициенты со значением +12 или -18 будут изменены на +2 и -8 соответственно.

Например

input = '3xy+y-2x+2xy'

Мой процесс пока что дает мне:

Var = ['xy', 'y', 'x']
Coe = ['+5', '+1', '-2']

Тогда я получил промежуточный результат: IR = ['+5xy', '+1y', '-2x']

Мое текущее решение:

[(e[0]+e[2:]) if (e[1]== '1' and e[2].isalpha() ) else e for e in IR ]

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

Спасибо.

Редактировать: код, который у меня есть для этого вопроса.Я все еще работаю над его отладкой.

def simplify(poly):

    #If the first coefficient is positive, then I add a + for calculation later on
    if poly[0] !='-':
        poly = '+'+poly
    L = list(poly)

    #Put each monomial in a list as an element
    Temp, e = [], ''
    for i in L:
        if i != '+' and i != '-':
            e += i
        else:
            Temp.append(e)
            e = ''
            e += i

    #The last one will be left out and the first one will be None
    Temp.append(e)
    Temp.pop(0)

    #If the monomial only has a + or - in front of it, then give it a '1' so it's easier for calculation
    SortAndGiveOne = [''.join(e[0] + '1' + e[1:]) if not e[1].isdigit() else e for e in Temp]

    #Try to get letters from each element of the list
    Var = [''.join(sorted(i for i in e if i.isalpha())) for e in SortAndGiveOne]
    #Try to get coefficients from each element of the list
    Coe = [''.join(i for i in e if not i.isalpha()) for e in SortAndGiveOne]

    #Calculation of equivalent monomials
    newvar = []
    newcoe = []
    for va, co in zip(Var, Coe):
        try:
            ind = newvar.index(va)
            newcoe[ind] = str(int(newcoe[ind]) + int(co))
        except ValueError:
            newvar.append(va)
            newcoe.append(co)

    # Put the new lists together
    Put_t = list(map(lambda x,y : y + x, newvar, newcoe))

    # Add the plus sign as it will be gone if there was calculation involved.
    FinalSign = ['+'+ e if e[0] != '+' and e[0] != '-' else e for e in Put_t]

    #Delete the elements with 0 as coefficient
    Delete0 = [e for e in FinalSign if not e[1]=='0']

    #Change the +1 and -1 coefficients to + and - 
    Change1 = [(e[0]+e[2:]) if (e[1]== '1' and e[2].isalpha() ) else e for e in Delete0 ]

    #Sort the list based on length and then lexi order
    FS_sort = sorted(Change1, key = lambda s: (len(''.join(filter(str.isalpha, s))), (''.join(filter(str.isalpha, s)))))

    #Join together as a list
    JT = ''.join(FS_sort)

    #Delete leading plus sign
    if JT[0] == '+':
        JT = JT[1:]

    return JT

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Предполагая, что могут быть числа с более чем двумя цифрами, ваш код содержит ошибки, например:

IR = ['5xy', '51y', '-2x']
result = [(e[0]+e[2:]) if (e[1]== '1' and e[2].isalpha() ) else e for e in IR ]
print(result)

возвращает:

['5xy', '5y', '-2x']

Возможно, будет более питонский способ использованиявместо этого:

def transform(e):
    multiplier = ''.join(c for c in e if c.isnumeric())
    return e[0] + e[2:] if multiplier == '1' else e


IR = ['5xy', '51y', '-2x']
result = [transform(e) for e in IR]
print(result)

IR = ['5xy', '+1y', '-2x']
result = [transform(e) for e in IR]
print(result)

Выход

['5xy', '51y', '-2x']
['5xy', '+y', '-2x']

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

0 голосов
/ 04 декабря 2018

Похоже, вы только пытаетесь изменить ['5xy', '+1y', '-2x'] на ['5xy', '+y', '-2x'] и т. Д. В этом случае я бы использовал регулярное выражение:

import re
newlist = [re.sub('(?<=[+-])1(?=[A-Za-z])', '', e) for e in your_list]

test:

k = ['5xy', '+1y', '-2x', '-1xy', '+11xy']
newlist = [re.sub('(?<=^[+-])1(?=[A-Za-z])', '', e) for e in k]
>>> newlist
['5xy', '+y', '-2x', '-xy', '+11xy']

это выглядит не намного лучше, чем ваше решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...