Я работаю над своими навыками понимания списков, ищу упражнения, чтобы отточить свое понимание. Но я достиг одного, который я не могу обойти. Допустим, мне нужен список всех возможных списков, содержащих 3 случайных цифры в диапазоне (1,3), где сумма каждого списка не равна 3.
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 1], [0, 2, 0] ...]
Очевидно, мне нужно сделать это с помощью вложенных списков. Но я не совсем уверен, как это сделать. Насколько мне известно, я не могу присвоить список переменной в понимании списка. Но мне нужна эта переменная для ссылки на вывод:
list7 = [[randint(0,2) for x in range(3)] for y if sum(y) != 3]
Это дает мне синтаксическую ошибку. Сначала я попытался присвоить внутренний список переменной, и это тоже не работает:
y = [randint(0,2) for x in range(3)]
list7 = [y for y if sum(y) != 3]
Однако меня смущает то, что "y" здесь вообще не дает ошибки. Он ведет себя так, как я ожидаю, хотя randint не присвоен «x». Видимо, я чего-то тут не понимаю. Итак, вот мой вопрос: как я могу повторить вложенный список в понимании списка, если я не могу назначить его переменной в понимании? Заранее спасибо.
Я не вижу смысла в переполнении стека, если единственная помощь, которую я могу получить для моего понимания, это «иди прочитай документацию и попробуй решить свою проблему», Питер. Я делал именно это, и у меня возникли проблемы. Вот почему я пришел сюда.
Понимание внешнего списка не является пониманием списка в list7
, потому что ничего не повторяется. т.е. пункт in foo
.
@PleasantNightmares жаль, что ты так думаешь. как указывает @dpwrussel, в вашем понимании второго списка нет in
. Некоторые вещи просто требуют много времени, перепроверки и т. д. Вы получите это.
Как я указал в своем комментарии, проблема с вашим решением заключается в том, что понимание внешнего списка не имеет итерации. Так как же он узнает, сколько результатов нужно произвести или когда прекратить производить результаты?
Также есть проблема с пунктом if
. В вашем if
вы делаете sum(y)
, что, как я полагаю, должно было означать «выполнить сумму результата [randint(0,2) for x in range(3)]
». Это в обратном порядке, потому что if
выполняется первым. Кроме того, y является переменной цикла для текущего элемента в итераторе, а не результатом понимания списка для этого элемента.
Другая проблема с вашим решением заключается в том, что вы используете randint
. Таким образом, вы можете создавать одни комбинации много раз, а другие — ни разу. Это несколько не по делу.
Я думаю, вероятно, вы хотели превратить что-то подобное в понимание списка.
results = []
for i in range(3):
for j in range(3):
for k in range(3):
if i + j + k != 3:
results.append([i, j, k])
Что вполне выполнимо, но ответ не во вложенных списках, потому что это нужно, когда вам нужно генерировать списки списков, и в этом случае только вашему внешнему списку нужны понимания, ваши внутренние списки - это всего 3 цифры в контейнере. С тем же успехом это мог быть кортеж.
Лучше всего думать об этом с точки зрения того, что вы хотите получить, список списков. Это означает, что вам нужно что-то, что генерирует список, который содержит другие списки.
Итак, вы хотите сгенерировать эти 3 цифры, проверьте, составляют ли они в сумме 3, а если нет, то они являются одним из элементов, которые добавляются к вашим результатам в виде списка. Вы можете воспользоваться тем фактом, что списки в python поддерживают несколько итераторов, чтобы добиться того же, что и вложенные циклы for.
results = [
[i, j, k]
for i in range(3) for j in range(3) for k in range(3)
if i + j + k != 3
]
См. официальные документы для большего количества полезных примеров: http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions
Редактировать:
Мне пришло в голову, что вы пытались сделать это:
results = [
item for item in [
[i, j, k]
for i in range(3) for j in range(3) for k in range(3)
]
if sum(item) != 3
]
Что немного больше похоже на ваш код. Это эквивалентно с точки зрения результатов, но может быть намного менее эффективным (как с точки зрения процесса, так и с точки зрения памяти), потому что в этом примере вы создаете все [i, j, k]
возможности в список, а затем фильтруете их до тех, которые не подходят. в сумме 3. Лучше вообще никогда не составлять эти списки. для этого тривиального примера это не имеет большого значения, но если [x, y, z]
было бы дорого построить или каждый элемент использовал нетривиальный объем памяти, это могло бы иметь значение.
или просто [t for t in [(x, y, z) for x in range(3) for y in range(3) for z in range(3)] if sum(t) != 3]
злоупотреблять пониманием списка.
Это то же самое, что и мое альтернативное решение, просто написанное одной строкой и использующее кортеж для контейнера!
Попробуйте работать изнутри, чтобы убедиться, что вы понимаете свои структуры данных и их содержимое. Понимание списков хорошо описано в документации по python, включая пример, очень близкий к вашему. Кроме того, решение ваших собственных синтаксических проблем научит вас большему, чем получение ответа здесь.