#list #list-comprehension
#Список #понимание списка
Вопрос:
Я работаю над своими навыками понимания списка, ищу упражнения, чтобы улучшить свое понимание. Но я достиг того, что, похоже, не могу обойти. Допустим, мне нужен список всех возможных списков, содержащий 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». По-видимому, я чего-то здесь не понимаю. Итак, вот мой вопрос: как я могу повторить вложенный список в понимании списка, если я не могу присвоить его переменной в понимании? Заранее спасибо.
Комментарии:
1. Попробуйте работать изнутри, чтобы убедиться, что вы понимаете свои структуры данных и их содержимое. Понимание списков хорошо описано в документах python, включая пример, очень близкий к вашему. Кроме того, решение ваших собственных синтаксических проблем научит вас большему, чем получение ответа здесь.
2. Я не вижу смысла в переполнении стека, если единственная помощь, которую я могу получить за свое понимание, — это «иди, прочитай документацию и попробуй решить свою собственную проблему», Питер. Я делал именно это, и у меня возникли проблемы. Вот почему я пришел сюда.
3. Понимание внешнего списка не является пониманием списка
list7
, потому что ничего не повторяется. Т.е.in foo
предложение.4. @PleasantNightmares жаль, что вы так думаете. как указывает @dpwrussel,
in
в вашем втором понимании списка нет. Некоторые вещи просто требуют много внимания, перепроверки и т. Д. Вы получите это.
Ответ №1:
Как я указал в своем комментарии, проблема с вашим решением заключается в том, что понимание внешнего списка не имеет итерации. Итак, как он узнает, сколько результатов нужно получить или когда прекратить выдачу результатов?
Существует также проблема с вашим if
предложением. В вашем if
you do 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]
было дорого построить или каждый элемент использовал нетривиальные объемы памяти, это может иметь значение.
Комментарии:
1. или просто
[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]
злоупотреблять пониманием списка.2. Это точно то же самое, что и мое альтернативное решение, просто написанное в одну строку и использующее кортеж для контейнера!