Как реализовать код для получения списка аргументов или списка кортежей? - PullRequest
0 голосов
/ 15 октября 2019

У меня есть MSA (множественное выравнивание последовательностей), и я хотел бы использовать последовательности в качестве аргумента для моей функции расстояния Хэмминга. Я получил предложение использовать некоторые вещи itertools. Я не знаю, правильно ли я понял, но мне кажется, что это так.

Я попробовал это:

def hamming_dist(s1, s2):
    assert len(s1) == len(s2)
    hd = 0
    for b1, b2 in zip(s1, s2):
        if b1 != b2:
            hd += 1
    return hd

def imap(function, *iterables):
    iterables = map(iter, iterables)
    while True:
        args = tuple([next(it) for it in iterables])
        print(args)
        if function is None:
            yield tuple(args)
        else:
            yield function(*args)

tup = ('ATGTG', '-TG-G'), ('A-GT-', 'ATG-G')
distances = imap(hamming_dist, *tup)
for dist in distances:
    print(dist)

('ATGTG', 'A-GT-')
2
()
TypeError: hamming_dist() missing 2 required positional arguments: 's1' and 's2'

Получил эту ошибку, и я пытаюсь выяснить! Я не понимаю, почему imap работает в первом случае (первый кортеж), но во втором - не получилось.
Может быть, из-за потребленного iter? Кто-нибудь из вас может помочь мне понять, что я делаю неправильно!?

Если присмотреться, я получил, что функция imap возвращает только один аргумент (первый кортеж, а затем второй пустой). Хмммм ...

Я изменил функцию imap на:

def imap(function, *iterables):
    iterables = map(iter, iterables)
    for it in iterables:
        args = tuple(it)
        if function is None:
            yield tuple(args)
        else:
            yield function(*args)    

И теперь она возвращает ожидаемый ответ, но мне нужно улучшение, чтобы сравнить все последовательности друг с другом. думаю, мне понадобится что-то вроде перестановки itertools.

Но все равно спасибо за ваше время, ребята.

Извините, что беспокою вас! Урок усердно пытался перед тем, как спросить.

Спасибо заваше время.

Пауло

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Попробуйте изменить imap на:

def imap(function, *iterables):
iterables = (x for x in iterables)
while True:
    if function is None:
        yield tuple(args)
    else:
        try:
            yield function(*next(iterables))
        except StopIteration:
            break

Обратите внимание, этот код, вероятно, не тот, который вы хотите использовать на более широкой картинке, но он близок к коду, который вы дали. Это совсем не идиоматично.

Например, почему бы не попробовать сопоставить hamming_distace с вашим списком итераций?

0 голосов
/ 15 октября 2019

Я все понял так:

def hamming_dist(s1, s2):
    assert len(s1) == len(s2)
    hd = 0
    for b1, b2 in zip(s1, s2):
        if b1 != b2:
            hd += 1
    return hd

def imap(function, *iterables):
    iterables = map(iter, iterables)
    for it in iterables:
        args = tuple(it)
        if function is None:
            yield tuple(args)
        else:
            yield function(*args) 


distances = imap(hamming_dist, *itertools.combinations(ls,2))
for dist in distances:
    print(dist)

Это дает правильные ответы в моем примере с игрушкой. Я проверю с более реальным MSA.

Спасибо всем за ваше время! Если у вас есть лучшее решение, пожалуйста, дайте мне знать.

Спасибо

...