Как вернуть список элементов в строке при сохранении исходного порядка элементов в Python - PullRequest
0 голосов
/ 27 января 2020

Я застрял в этой задаче кодирования из Codewars:

"Реализовать функцию unique_in_order, которая принимает в качестве аргумента последовательность и возвращает список элементов без каких-либо элементов с одинаковым значением рядом друг с другом и сохранением исходный порядок элементов. "

" Например:

unique_in_order('AAAABBBCCDAABBB') == ['A', 'B', 'C', 'D', 'A', 'B']
unique_in_order('ABBCcAD')         == ['A', 'B', 'C', 'c', 'A', 'D']
unique_in_order([1,2,2,3,3])       == [1,2,3]

"

Вот как далеко я смог зайти так далеко:

def unique_in_order(iterable):
    iterable= list(set(iterable))

    return sorted(iterable)

Что дает мне вывод:

['A', 'B', 'C', 'D']

Для следующего ввода:

['AAAABBBCCDAABBB'] 

вместо желаемого вывода:

['A', 'B', 'C', 'D', 'A', 'B'] 

I ценю твою помощь.

Ответы [ 5 ]

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

Вы можете легко сделать это с помощью понимания списка, используя zip и немного нарезки. Это в основном парный рецепт без использования itertools. Если хотите, вы можете посмотреть этот рецепт, если он вам тоже нужен.

[it[0]] + [nc for c, nc in zip(it, it[1:]) if c != nc]

Для ясности c - текущий символ nc - следующий символ в паре.


>>> it = 'AAAABBBCCDAABBB'
>>> [it[0]] + [nc for c, nc in zip(it, it[1:]) if c != nc]
['A', 'B', 'C', 'D', 'A', 'B']

Это может быть показано как стандарт для l oop, а также для большей ясности:

result = [it[0]]
for c, nc in zip(iterable, iterable[1:]):
    if c != nc:
        result.append(nc)
1 голос
/ 27 января 2020

Вы можете попробовать это.

Итерация по строке. Когда элемент ith и ith + 1 не совпадают, добавьте элемент ith в список `res.

def unique_order(_iter):
    if not _iter:
        return []
    res=[]
    for i in range(0,len(_iter)-1):
        if _iter[i]!=_iter[i+1]:
            res.append(_iter[i])
    res.append(_iter[-1])
    return res

unique_order('AAAABBBCCDAABBB') #output is ['A', 'B', 'C', 'D', 'A', 'B']

itertools.groupby() можно использовать здесь.

from itertools import groupby
def unique_order(_iter):
    return [k for k, g in groupby(_iter)] #'AAAABBBCCDAABBB'--> ['A', 'B', 'C', 'D', 'A', 'B']
1 голос
/ 27 января 2020

Самый простой способ сделать это:

>>> string = "AAAABBBCCDAABBB"
>>> new_list = []
>>> for i in string:
...     if not new_list:
...             new_list.append(i)
...     elif new_list[-1] != i:
...             new_list.append(i)
...
>>> new_list
['A', 'B', 'C', 'D', 'A', 'B']

Вы можете обернуть это в функцию, если это необходимо.

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

set создает объект с каждым элементом в списке, встречающимся только один раз. Вместо встроенной функции вам придется написать что-то самостоятельно. Как это сделать?

Сначала создайте ввод и список, в котором будет сохранен ваш результат:

input_word = 'aabbbaaa'
output_list = []

Теперь мы сделаем l oop над словом, и каждый новое письмо мы добавляем. Поэтому нам нужно отследить, что такое «текущая» буква:

current_letter = None

Сначала мы установили для нее значение Нет, потому что у нас еще нет текущей буквы. Теперь мы находимся над словом:

for letter in input_word:
    if letter != current_letter:
        output_list.append(letter)
        current_letter = letter
print(output_list)
>>> ['a', 'b', 'a']
0 голосов
/ 27 января 2020

Вы должны использовать itertools.groupby. Требуемое поведение аналогично команде uniq. Как говорит do c, groupby имеет похожий характер поведения.

>>> import itertools
>>> [k for k, _ in itertools.groupby('AAAABBBCCDAABBB')]
['A', 'B', 'C', 'D', 'A', 'B']
>>> 

Этот вопрос описывает поведение, подобное вашему.

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