Разница между пониманием списка и для цикла - PullRequest
0 голосов
/ 06 марта 2019

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

Подход 1

set1 = [[]]
num = [1,2,3]
for n in num:
    for s in set1:
        set1 += [ s + [n] ]
print(set1)

Подход 2

set1 = [[]]
num = [1,2,3]
for n in num:
    set1 += [ s + [n] for s in set1]
print(set1)

Approach 1 зависает, а Approach 2 - нет и дает правильный результат.Я думаю, что причина в том, что:
1) Approach 1 добавляет элемент в set1 для каждого члена набора set1.Таким образом, цикл for никогда не заканчивается, потому что список set1 постоянно растет.
2) Approach 2 обновляет set1 после все элементы в set1 обрабатываются.Я на правильном пути, чтобы понять разницу между двумя подходами?Кроме того, могу ли я считать [ s + [n] for s in set1] списком, полученным из следующего псевдокода?

tmp = []
for s in set1:
   tmp += [s + [n]]

Ответы [ 2 ]

1 голос
/ 06 марта 2019

Я думаю, что ваши два подхода не равны.

Второй подход - "расширить set1 после вычисления списка".Таким образом, эквивалент подхода 2 должен выглядеть следующим образом:

set1 = [[]]
num = [1,2,3]
for n in num:
    tmp = []
    for s in set1:
        tmp += [ s + [n] ]
    set1 += tmp
print(set1)

Почему вы подходите к 1 зависанию?Это не зависание, это зацикливание навсегда, потому что вы расширяете свой список, проходя его.

    for s in set1:
        set1 += [ s + [n] ]

Каждый раз, когда вы получаете следующий элемент set1, ваш set1 становится длиннее.

Это действительно плохая идея, чтобы изменить элемент во время его прохождения.Не делай этого.Создание средней переменной, такой как ваш псевдокод, более безопасно и понятно.

1 голос
/ 06 марта 2019

Проблема в том, что вы изменяете список, который вы повторяете в цикле for s in set1.Этого можно избежать, используя copy (), чтобы убедиться, что вы выполняете итерацию для отдельного экземпляра списка: for s in set1.copy().Вы также можете ограничить длину цикла: for s in set1[:len(set1)]

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