Python: использование цикла while или for для перебора списков

#python #list #while-loop

#python #Список #цикл while

Вопрос:

Я пытаюсь соединить значения в кортежах в списке без использования словаря. В частности, у меня есть этот список:

 adjList = [('0', '3'), ('1', '0'), ('3', '2'), ('4', '2'), ('5', '4'), ('7', '9'), 
('8', '7'), ('9', '6'), ('2', '1'), ('2', '6'), ('6', '5'), ('6', '8')]
  

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

 newList = ['1', '0']
  

затем добавьте второе значение кортежа из adjList, если первое значение этого кортежа совпадает с последним значением newList, таким образом:

 newList = ['1', '0', '3']
  

Затем удалите (‘1’, ‘0’) и (‘0’, ‘3’) из adjList.

ЗАТЕМ я хочу повторять это действие до тех пор, пока последнее значение в newList БОЛЬШЕ НЕ будет соответствовать первому значению кортежа из adjList. У меня возникают большие проблемы с поиском логической комбинации циклов while или for, которые могут это сделать, и я был бы признателен за любую помощь.

Мой код пока:

 adjList = [('0', '3'), ('1', '0'), ('3', '2'), ('4', '2'), ('5', '4'), ('7', '9'), 
('8', '7'), ('9', '6'), ('2', '1'), ('2', '6'), ('6', '5'), ('6', '8')]

firstNode = random.choice(adjList)
newList = []
newList.append(firstNode[0])
newList.append(firstNode[1])
adjList.remove(firstNode)

## I need to repeat the following block of code:

for ax,bx in adjList:
    if newList[-1] == ax:
        adjList.remove((ax,bx))
        newList.append(bx)
        break
  

Все работает так, как должно, но, конечно, я получаю только 3 значения в newList в конце. Я не могу понять, как повторить этот последний блок кода, пока у меня не закончатся кортежи в adjList.

Заранее спасибо за любую помощь.

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

1. Как насчет случая, когда существует множество возможных кортежей для выбора adjList ? Допустим, что случайно выбранный кортеж — это ('9', '6') какое было бы правильное значение newList ?

2. Правильное значение newList тогда было бы [‘9’, ‘6’, ‘5’]. Можно просто взять первый кортеж с соответствующим значением.

3. Я думаю, было бы проще отлаживать, если бы вы не выбирали случайный узел.

4. Случайный узел не имеет ничего общего с блоком кода, который мне нужно повторить. Думайте об этом просто как о двух начальных списках, если так проще: adjList как опубликовано, и newList = [‘1’, ‘0’], затем мне нужно перейти оттуда, сопоставив значения и добавив их в newList.

Ответ №1:

Вы могли бы просто запустить внешний while цикл, пока в adjList нем еще есть элементы. Внутренний цикл может выбрать первый подходящий элемент из adjList и добавить результат к newList . В случае, если внутренний цикл не может найти подходящий элемент, внешний цикл должен быть завершен.

Вот пример из приведенного выше:

 import random

adjList = [('0', '3'), ('1', '0'), ('3', '2'), ('4', '2'), ('5', '4'), ('7', '9'),
('8', '7'), ('9', '6'), ('2', '1'), ('2', '6'), ('6', '5'), ('6', '8')]

newList = list(adjList.pop(random.randint(0, len(adjList) - 1)))

while adjList:
    for i, (src, dest) in enumerate(adjList):
        if src == newList[-1]:
            del adjList[i]
            newList.append(dest)
            break
    else:
        break

print('Result: {}'.format(newList))
print('Remaining: {}'.format(adjList))
  

Вывод:

 Result: ['4', '2', '1', '0', '3', '2', '6', '5', '4']
Remaining: [('7', '9'), ('8', '7'), ('9', '6'), ('6', '8')]
  

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

1. Это также отличное решение моей проблемы! Большое спасибо, я ценю помощь.

Ответ №2:

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

Я добавил while цикл, который выполняется каждый раз, когда происходит изменение структуры (в основном, каждый раз, когда кортеж, первый элемент которого совпадает с последним элементом в newList ):

 #!/usr/bin/env python
import random

adjList = [('0', '3'), ('1', '0'), ('3', '2'), ('4', '2'), ('5', '4'), ('7', '9'),
           ('8', '7'), ('9', '6'), ('2', '1'), ('2', '6'), ('6', '5'), ('6', '8')]

firstNode = random.choice(adjList)
newList = []
newList.append(firstNode[0])
newList.append(firstNode[1])

changes_made = True
while changes_made:
    changes_made = False
    for item in adjList:
        if item[0] == newList[-1]:
            newList.append(item[-1])
            adjList.remove(item)
            changes_made = True
            break

print newList