Выравнивание двух строк: Bigramm / Buble - PullRequest
3 голосов
/ 30 января 2020

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

, например. Ввод:

вывод:

['H', 'o', 'u', 's', 'e'] ['H', 'o', 's']

желаемый результат:

['H', 'o', 'u', 's', 'e'] 
['H', 'o', ,'0','s', '0']

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

Ответы [ 4 ]

2 голосов
/ 30 января 2020

Быстрый и грязный подход:

l1 = ['H', 'o', 'u', 's', 'e'] 
l2 = ['H', 'o', 's']

l2, l1 = sorted((l1, l2), key=len)
l = len(l1)
j = 0

res = []
for i in range(l):
  try:
    if l1[i]==l2[j]:
      res.append(l1[i])
      j += 1
    else:
      res.append(None)    
  except IndexError:
    res.extend([None] * (l-j))
    break

print(res)  # -> ['H', 'o', None, 's', None]

Обратите внимание, что необходимы пояснения! (см. комментарий @ yatu)

Также обратите внимание, что я изменил ваш '0' на None. Использование '0' является плохой идеей, поскольку, по крайней мере в теории, ваши два начальных списка могут содержать это, и вы не сможете различить совпадение и несоответствие.


Я определенно с нетерпением жду более элегантного подхода к этой интересной проблеме!

1 голос
/ 30 января 2020

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

class Track:
   def __init__(self, v):
      self.v = iter(v)
   def __getitem__(self, val):
      self.v = self.v if (r:=next(self.v, None)) is None or r == val else iter([r, *self.v])
      return '0' if r != val else r

d1, d2 = ['H', 'o', 'u', 's', 'e'], Track(['H', 'o', 's'])
result = [d2[i] for i in d1]

Вывод:

['H', 'o', '0', 's', '0']
1 голос
/ 30 января 2020

быстрая функция:

def my_func(l1, l2):
    consume_l2 = l2.copy()
    return [l2.pop(l2.index(c)) if c in l2 else '0' for c in l1]

l1 = ['H', 'o', 'u', 's', 'e']
l2 = ['H', 'o', 's']
print(my_func(l1, l2))

вывод:

['H', 'o', '0', 's', '0']

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

[l2.pop(l2.index(c)) if c in l2 else '0' for c in l1]
1 голос
/ 30 января 2020

Вы можете сделать это с for l oop и if else. Вам просто нужно использовать дополнительный индекс, чтобы отслеживать более короткий список

list1 = ['H', 'o', 'u', 's', 'e']
list2 = ['H', 'o', 's']
list3 = []

j = 0
for i in range(len(list1)):
    if j < len(list2) and list1[i] == list2[j]:
        list3.append(list1[i])
        j += 1
    else:
        list3.append('0')
    i += 1

print(list3) # ['H', 'o', '0', 's', '0']

или на основе list2

for i in range(len(list1)):
    if i >= len(list2):
        list2.append('0')
    elif list1[i] != list2[i]:
        list2.insert(i, '0')

print(list2) # ['H', 'o', '0', 's', '0']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...