Получить элементы из списка, содержащего строку непрерывных символов и непрерывный последующий элемент

#python #for-loop #enumerate

#питон #for-цикл #перечислять

Вопрос:

У меня есть список строк, таких как:

 my_list = ['abc','bcd','cde','def','efc']
 

Если вы хотите получить результат, основанный на нижеприведенных условиях:

  • символы в строке являются непрерывными. Например: "a" , "b" , "c" , …
  • Последующие элементы в списке также являются непрерывными. Например: "abc" , "bcd" , «cde», …
  • Если какое-либо из вышеперечисленных условий не выполняется, break итерация

Для приведенного выше примера мне нужно, чтобы выходные данные были похожи (вместе с индексом элементов).:

 0 abc
1 bcd
2 cde
4 efc
 

Вот код, который я пробовал:

 lst = ['abc','bcd','cde','def','efc']
for idx, i in enumerate(lst):
    if 'c' in i:
        #here should be the other condition
        print(idx,i)
 

Но он печатает только эти:

 0 abc
1 bcd
2 cde
 

Комментарии:

1. почему бы и нет def ? это также в непрерывном шаблоне или я упускаю какую-то логику?

2. понял, вы также должны c присутствовать

3. Что означает «непрерывный (непрерывный) индекс»? Вы хотите остановиться, если в нем нет ‘c’? Так что, может быть, добавление else: break помогает?

4. @YevhenKuzmovych вы поняли мою точку зрения, за исключением того, что else: break если первый элемент не содержит c t, он ничего не напечатает.

5. Вы не упомянули об этом в своем вопросе. Существует много способов его интерпретации. Поэтому вам необходимо предоставить более подробную информацию и / или примеры.

Ответ №1:

Вы можете найти код символа в юникоде, используя ord() . В приведенном ниже примере я использую zip() для итерации непрерывных символов в строке, а затем сопоставляю, чтобы их код unicode был непрерывным. Затем я использую all() , чтобы проверить, что все коды строки в юникоде являются непрерывными:

 my_list = ['abc','bcd','cde','def','efc']

for i, l in enumerate(my_list):
    # check if element is first element in list
    is_first = i == 0

    # check if all the chars are continuous in string
    is_continuous = all(ord(a) 1 == ord(b) for a, b in zip(l, l[1::]))

    # Match the continuation order from previous index element.
    # True, for 1st element
    is_previous_match = is_first or ord(my_list[i-1][0]) 1 == ord(l[0])

    if is_continuous and is_previous_match:
        print(i, l)
    else:
        break
 

который будет печатать:

 0 abc
1 bcd
2 cde
3 def
 

Комментарии:

1. Я думаю, что OP означает что-то другое — просто печатать строки, если они следуют условию и идут подряд в списке, а не фактические буквы в строках. Но я могу ошибаться.

2. Потому что он пишет о непрерывных индексах, а не о буквах.

3. У OP есть if 'c' in i условие в коде, что заставляет меня думать, что он ищет эту проверку. и их желаемый результат соответствует этому поведению. Согласно логике в вашем комментарии, def также должно присутствовать в желаемом выводе, верно?

4. Я имею в виду, что (ы) он (вероятно) ищет строки с ‘c’ в них, которые идут подряд в списке. Не буквы в самих строках, которые идут в алфавитном порядке подряд

5. спасибо за подробный ответ, но это работает только в том случае, если l в строке нет пробела, эта часть if 'c' in l — всего лишь пример разрыва индекса после нескольких совпадений, это не само значение

Ответ №2:

Я нашел гораздо более простое решение

 my_list = ['lol','abc','bcd','cd e','def','efc','das da']
index = []
for i,l in enumerate(my_list):
    if 'c' in l:
        index.append(i)
for l in my_list[index[0]:]:
    if 'c' in l:
        print(l)
    else:
        break
abc
bcd
cd e
 

Комментарии:

1. Я предложил вам в комментариях еще более простой, с takewhile() . Но если вам не нужны индексы, вы можете использовать еще более простой вариант: print(*takewhile(lambda x: 'c' in x, lst), sep='n')