Python: перестановки

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

Инструкции:

Чтобы программа перечислила все возможные маршруты, ей нужно немного поработать. Исправьте программу, добавив оператор if, который проверяет, включает ли маршрут все порты. Другими словами, убедитесь, что каждое из чисел 0, 1, 2, 3, 4 включено в список маршрутов. Обратите внимание, что нет необходимости проверять, что ни один порт не появляется дважды, поскольку в этом случае маршрут не может включать все пять портов.

Вам не нужно изменять оператор печати.

Это мой код, но он не работает. Как это можно исправить?

def main():
    portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]

    # don't change this bit - provided in exercise
    port1 = 0
    for port2 in range(1, 5):
        for port3 in range(1, 5):
            for port4 in range(1, 5):
                for port5 in range(1, 5):
                    route = [port1, port2, port3, port4, port5]

                    # instructions to add if statement that checks that the route includes all of the ports
                    # if "PAN" in route and "AMS" in route and "CAS" in route and "NYC" in route and "HEL" in route:
                    if all([val in route for val in portnames]):
                    
                        # do not modify the print statement
                        print(' '.join([portnames[i] for i in route]))

                    else:
                        continue

main()

Какие ограничения? Я разговариваю по телефону (ссылки очень раздражают), и этот вопрос может пережить эту ссылку. Пожалуйста, сделайте вопрос самодостаточным

roganjosh 18.12.2020 00:30

Вы должны быть более конкретными о том, что не работает. Каков ожидаемый результат? Какой результат вы получаете?

bananafish 18.12.2020 00:30

Подсказка в том, что ваш route — это просто список чисел на данный момент. Они должны быть именами портов. for port1 in portnames: и др.

bananafish 18.12.2020 00:31

Я предполагаю, что я не могу использовать «itertools», так как есть ограничение на последнюю строку (не меняя ее), но это было бы слишком просто. Кроме того, они уже предоставили большую часть кода.

william3031 18.12.2020 00:37

Не могу использовать itertools @chepner

william3031 18.12.2020 00:38

@ william3031 Вы сказали, что не можете использовать itertools, потому что не знаете, как изменить оператор print. Этому утверждению все равно, происходит ли route из product или из вашего ручного цикла. (Тем не менее, я удалил свой комментарий, потому что он не учитывал фиксированное значение port1.)

chepner 18.12.2020 00:39

Я отредактировал вопрос, чтобы отметить, что мне «не разрешено» использовать «itertools», а не «не могу» его использовать. Также отредактировано, чтобы показать, что было предоставлено и что было добавлено.

william3031 18.12.2020 00:41
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
7
1 226
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Добавление следующего оператора print перед условием if показывает ошибку:

# code before
    print(route)
    if all([val in route for val in portnames]):
# code after


# Output:
# [0, 4, 3, 2, 2]
# [0, 4, 3, 2, 3]
# [0, 4, 3, 2, 4]
# ...

route состоит из целых чисел, сгенерированных range. Вместо этого вы можете сделать заявление if:

if all([portnames.index(val) in route for val in portnames]):

Выход:

PAN AMS CAS NYC HEL
PAN AMS CAS HEL NYC
PAN AMS NYC CAS HEL
PAN AMS NYC HEL CAS
PAN AMS HEL CAS NYC
PAN AMS HEL NYC CAS
PAN CAS AMS NYC HEL
PAN CAS AMS HEL NYC
PAN CAS NYC AMS HEL
PAN CAS NYC HEL AMS
PAN CAS HEL AMS NYC
PAN CAS HEL NYC AMS
PAN NYC AMS CAS HEL
PAN NYC AMS HEL CAS
PAN NYC CAS AMS HEL
PAN NYC CAS HEL AMS
PAN NYC HEL AMS CAS
PAN NYC HEL CAS AMS
PAN HEL AMS CAS NYC
PAN HEL AMS NYC CAS
PAN HEL CAS AMS NYC
PAN HEL CAS NYC AMS
PAN HEL NYC AMS CAS
PAN HEL NYC CAS AMS

Спасибо. Это сработает, если я не изменю print(' '.join([portnames[i] for i in route]))?

william3031 18.12.2020 00:41

@ william3031 william3031 да, последний вывод получен из вашего кода, скопированного/вставленного только с измененным оператором if. Дополнительное утверждение print, которое я описал, не нужно — я включил его только для иллюстрации.

Tom 18.12.2020 00:46

Таким образом, маршруты являются числовыми, пока я пытаюсь сопоставить строки, и оператор if должен измениться?

william3031 18.12.2020 00:47

@william3031 точно, несколько вызовов range генерируют целочисленные позиции portnames, поэтому вы можете использовать index(), чтобы связать эти позиции с самими строками.

Tom 18.12.2020 00:53

Вы можете сделать это вместо понимания списка -

if set(range(len(portnames))).issubset(route)

Набор маршрутов (которые представляют собой индексы от 0 до 4) должен полностью содержать набор индексов имен портов (0-4). Если это True, то каждое имя порта будет существовать в маршруте и, таким образом, напечатано.

portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]

# don't change this bit - provided in exercise
port1 = 0
for port2 in range(1, 5):
    for port3 in range(1, 5):
        for port4 in range(1, 5):
            for port5 in range(1, 5):
                route = [port1, port2, port3, port4, port5]

                # instructions to add if statement that checks that the route includes all of the ports
                # if "PAN" in route and "AMS" in route and "CAS" in route and "NYC" in route and "HEL" in route:
                if set(range(len(portnames))).issubset(route):

                    # do not modify the print statement
                    print(' '.join([portnames[i] for i in route]))

                else:
                    continue
PAN AMS CAS NYC HEL
PAN AMS CAS HEL NYC
PAN AMS NYC CAS HEL
PAN AMS NYC HEL CAS
PAN AMS HEL CAS NYC
PAN AMS HEL NYC CAS
PAN CAS AMS NYC HEL
PAN CAS AMS HEL NYC
PAN CAS NYC AMS HEL
PAN CAS NYC HEL AMS
PAN CAS HEL AMS NYC
PAN CAS HEL NYC AMS
PAN NYC AMS CAS HEL
PAN NYC AMS HEL CAS
PAN NYC CAS AMS HEL
PAN NYC CAS HEL AMS
PAN NYC HEL AMS CAS
PAN NYC HEL CAS AMS
PAN HEL AMS CAS NYC
PAN HEL AMS NYC CAS
PAN HEL CAS AMS NYC
PAN HEL CAS NYC AMS
PAN HEL NYC AMS CAS
PAN HEL NYC CAS AMS

Есть дубликаты, например. в строке вывода AMS встречается четыре раза. AssertionError: False != True : Incorrect set of route combinations

william3031 18.12.2020 00:51

обновил.. случайно поменял код

Akshay Sehgal 18.12.2020 00:53
def main():
    portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]
    # https://sea-distances.org/
    # nautical miles converted to km
    D = [
            [0,8943,8019,3652,10545],
            [8943,0,2619,6317,2078],
            [8019,2619,0,5836,4939],
            [3652,6317,5836,0,7825],
            [10545,2078,4939,7825,0]
        ]
    # https://timeforchange.org/co2-emissions-shipping-goods
    # assume 20g per km per metric ton (of pineapples)
    co2 = 0.020
    route = []
    port1 = 0
    for port2 in range(1,5):
                for port3 in range(1,5):
                    for port4 in range(1,5):
                        for port5 in range(1,5):
                            result = [port1, port2, port3, port4, port5]
                            if 0 in result:
                                if 1 in result:
                                    if 2 in result:
                                        if 3 in result:
                                            if 4 in result:
                                                route.append(result)
    for singleRoute in route:
        distance = D[singleRoute[0]][singleRoute[1]] + D[singleRoute[1]][singleRoute[2]] + D[singleRoute[2]][singleRoute[3]] + D[singleRoute[3]][singleRoute[4]]
        emissions = distance * co2      
        print(' '.join([portnames[i] for i in singleRoute]) + " %.1f kg" % emissions)
main()

совет профессионального стиля: вы можете легко проверить, что маршрут включает все порты (пронумерованные 0, 1, ..., 4), используя наборы Python. Неуклюжий оператор if в примере решения можно заменить гораздо более элегантным:

если установить (маршрут) == установить (диапазон (5)):

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