Проверка последовательности в списке Python

Имею список [T20, T5, T10, T1, T2, T8, T16, T17, T9, T4, T12, T13, T18]

Я вырезал буквы T, преобразовал их в целочисленный тип и отсортировал список, чтобы получить следующее:

sorted_ids = [1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]

Я просматриваю список и проверяю, находится ли следующее число от текущего числа в числовой последовательности. Если нет, я хочу вставить "V" в его позицию.

В итоге список должен выглядеть так: [1, 2, V, 4, 5, V, V, 8, 9, 10, V, 12, 13, V, V, 16, 17, 18, V, 20]

Однако я не могу вставить точное число Против в нужные места.

def arrange_tickets(tickets_list):

    ids=[]
    for item in tickets_list:
        new_str=item.strip("T")
        ids.append(int(new_str))
    sorted_ids = sorted(ids)
    temp_ids = []
    print("Sorted: ",sorted_ids)
    #size = len(sorted_ids)
    for i in range(len(sorted_ids)-1):
        temp_ids.append(sorted_ids[i])
    
        if sorted_ids[i]+1 != sorted_ids[i+1] :
            temp_ids.insert(i+1,"V")
    print(temp_ids)
    #print(sorted_ids)
    

tickets_list = ['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']
print("Ticket ids of all the available students :")
print(tickets_list)
result=arrange_tickets(tickets_list)

Actual Result: [1, 2, 'V', 4, 'V', 5, 8, 'V', 9, 'V', 10, 12, 'V', 13, 16, 17, 18]

Expected Result: [T1, T2, V, T4, T5, V, V, T8, T9, T10, V, T12, T13, V, V, T16, T17, T18, V, T20]

можете ли вы предоставить полный пример кода? чтобы мы могли это проверить?

Fabian 06.01.2019 14:58

Я предоставил код.

HackersInside 06.01.2019 15:01

Вы хотите снова добавить букву T, когда весь процесс будет завершен?

Feelsbadman 06.01.2019 15:02

пожалуйста, проверьте свое форматирование

Fabian 06.01.2019 15:02

Да, я собираюсь добавить букву "Т" обратно

HackersInside 06.01.2019 15:03

Список всегда начинается с 1?

Bemmu 06.01.2019 15:05

да, список всегда начинается с 1 (пока).

HackersInside 06.01.2019 15:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
7
5 424
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Вот решение:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]

def arrange(inList):
    newList = []
    newList.append('T'+str(inList[0]))
    for i in range(1,len(inList)):
        diff = inList[i] - inList[i-1]
        if diff > 1:
            for d in range(diff-1):
                newList.append('V')
            newList.append('T'+str(inList[i]))
        else:
            newList.append('T'+str(inList[i]))
    return newList

print(arrange(sorted_ids))

Вывод:

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

Отлично, понравилась твоя логика. Думаю, главное, чего не хватало в моем коде, - это внутренний цикл. Спасибо. В любом случае, если бы я хотел прикрепить буквы Т к числам, в чем должна быть логика? Перебрать и присоединить букву «Т» к каждому элементу?

HackersInside 06.01.2019 15:11

@HackersInside спасибо, я обновил свой ответ, чтобы он соответствовал вашему ожидаемому результату. Вы можете взглянуть и сказать мне, нормально ли это.

Vasilis G. 06.01.2019 15:12
temp_ids.insert(i+1,"V") 

Это неприятное заявление. Обновите свой код следующим образом

temp_ids=[]

for i in range(len(sorted_ids)-1):
    temp_ids.append(sorted_ids[i])

    if sorted_ids[i]+1 != sorted_ids[i+1] :
        for i in range(sorted_ids[i+1]-sorted_ids[i]-1):
            temp_ids.append("V") # appends as many V's as required

temp_ids.append(sorted_ids[-1]) # appends last element

Это должно работать Предположим, отсортированный массив [1,2,6]

Итак, наш желаемый результат должен быть [1,2, 'V', 'V', 'V', 6]. Так каждый раз

sorted_ids[i]+1 != sorted_ids[i+1]

условие выполнено, нам нужно будет добавить несколько чисел V. Теперь, чтобы определить, сколько V мы добавляем, посмотрите, что между 2 и 6 будет добавлено 3 V. В общем, мы добавляем (sorted_ids [i + 1] - sorted [i] -1) V.

Теперь посмотри на эту строку

for i in range(len(sorted_ids)-1):

Из-за этой строки наш список выполняется только для [1,2] в [1,2,6], и мы никогда не добавляем 6 в наш цикл For Loop, поэтому после выхода из цикла For Loop он был добавлен.

Не могли бы вы пояснить, почему мы должны добавлять последний элемент отдельно?

HackersInside 06.01.2019 15:18

Вот еще одно решение, которое стоит рассмотреть:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]

for i in range(min(sorted_ids), max(sorted_ids)): 
     if sorted_ids[i] != i + 1: 
         sorted_ids.insert(i, 'V')

final_list = [ "T" + str(x) if isinstance(x, int) else x for x in sorted_ids]

результат:

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

ммм, это кажется неправильным: ['T1', 'V', 'T2', ...] тебе не кажется?

Feelsbadman 06.01.2019 15:43
Ответ принят как подходящий

Вот список, который дает вам то, что вы хотите:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]
a = sorted_ids[0]
b = sorted_ids[-1]
nums = set(sorted_ids)
expected = ["T" + str(i) if i in nums else 'V' for i in range(a,b+1)]
print(expected)

Вывод:

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

Спасибо, не могли бы вы подробнее рассказать об использовании набора?

HackersInside 06.01.2019 15:13

@HackersInside Целью set является преобразование in из оператора O(n) в оператор O(1). В этом случае это не имеет большого значения, но для больших наборов данных было бы неэффективно проводить несколько линейных сканирований по списку.

John Coleman 06.01.2019 15:15

Сначала подумайте, какие идентификаторы должны быть в списке, предполагая, что они начинаются с 1 и заканчиваются самым большим из имеющихся. Затем проверьте, присутствует ли каждый ожидаемый идентификатор на самом деле, и если нет, поставьте там букву «V». В качестве побочного эффекта это также сортирует список.

def arrange_tickets(tickets_list):
    ids = [int(ticket[1:]) for ticket in tickets_list]
    expected_ids = range(1, max(ids) + 1)
    return ["T%d" % n if n in ids else "V" for n in expected_ids]

tickets_list = ['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']
print("Ticket ids of all the available students :")
print(tickets_list)
result=arrange_tickets(tickets_list)
print(result)   

результат:

Ticket ids of all the available students :
['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

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

from itertools import groupby
from operator import itemgetter

def groupby_consecutive(lst):
    for _, g in groupby(enumerate(lst), lambda x: x[0] - x[1]):
        yield list(map(itemgetter(1), g))

sorted_ids = [1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]
print(list(groupby_consecutive(lst=sorted_ids)))
# [[1, 2], [4, 5], [8, 9, 10], [12, 13], [16, 17, 18], [20]]

Затем вы можете создать функцию, которая получает перемежающиеся значения V из предыдущих группировок:

def interperse(lst):
    for x, y in zip(lst, lst[1:]):
        yield ["V"] * (y[0] - x[-1] - 1)

groups = list(groupby_consecutive(lst))
print(list(interperse(groups)))
# [['V'], ['V', 'V'], ['V'], ['V', 'V'], ['V']]

Затем вы можете, наконец, объединить приведенные выше результаты:

def add_prefix(lst, prefix):
    return [prefix + str(x) for x in lst]

def create_sequences(lst, prefix='T'):
    groups = list(groupby_consecutive(lst))
    between = list(interperse(groups))

    result = add_prefix(groups[0], prefix)
    for x, y in zip(between, groups[1:]):
        result.extend(x + add_prefix(y, prefix))

    return result

sorted_ids = [1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]
print(create_sequences(lst=sorted_ids))
# ['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

За один снимок прямо из исходного массива

array = ['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']

Вы можете определить метод, который выполняет всю работу:

def add_vs_between_not_cons(array):
  iterable = sorted(array, key= lambda x: int(x[1:]))
  i, size = 0, len(iterable)
  while i < size:
    delta = int(iterable[i][1:]) - int(iterable[i-1][1:])
    for _ in range(delta-1):
      yield "V"
    yield iterable[i]
    i += 1

Итак, вы можете вызвать:

print(list(add_vs_between_not_cons(array)))

#=> ['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

мое решение для запросов infytq:

def arrange_tickets(tickets_list):
    ids = [int(ticket[1:]) for ticket in tickets_list]
    expected_ids = range(1, max(ids) + 1)
    listt=["T%d" % n if n in ids else "V" for n in expected_ids]
    list1=listt[0:10]
    list2=listt[11:]
    for i in range(10):
        if 'V' in list2:
            list2.remove('V')
    for j in range(0,len(list2)):
        for n, i in enumerate(list1):
            if i == 'V':
                list1[n] = list2[j]
                j+=1
    return list1
tickets_list = ['T5','T7','T1','T2','T8','T15','T17','T19','T6','T12','T13']
print("Ticket ids of all the available students :")
print(tickets_list)
result=arrange_tickets(tickets_list)
print()
print("Ticket ids of the ten students in Group-1:")
print(result[0:10])

Другие вопросы по теме