Понимание списка предоставляет краткий способ создания списков. Распространенными приложениями являются создание новых списков, в которых каждый элемент является результатом некоторых операций, применяемых к каждому элементу другой последовательности или повторяющихся, или для создания подпоследовательности из тех элементов, которые удовлетворяют определенному условию.
Что касается вашего вопроса, понимание списка выполняет то же самое, что и следующий "простой" код Python:
>>> l = [] >>> for x inrange(10): ... l.append(x**2) >>> l [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Как это записать в одну строку? Хм ... мы можем ... наверное...использовать map() с lambda:
В принципе, мы можем делать что угодно с x. Не только x**2. Например, запустите метод x:
>>> [x.strip() for x in ('foo\n', 'bar\n', 'baz\n')] ['foo', 'bar', 'baz']
Или использовать x в качестве аргумента другой функции:
>>> [int(x) for x in ('1', '2', '3')] [1, 2, 3]
Мы также можем, например, использовать x в качестве ключа dict объекта. Давайте посмотрим:
>>> d = {'foo': '10', 'bar': '20', 'baz': '30'} >>> [d[x] for x in ['foo', 'baz']] ['10', '30']
Как насчет комбинации?
>>> d = {'foo': '10', 'bar': '20', 'baz': '30'} >>> [int(d[x].rstrip('0')) for x in ['foo', 'baz']] [1, 3]
И так далее.
Вы также можете использовать if или if...else в понимании списка. Например, вам нужны только нечетные числа в range(10). Вы можете сделать:
>>> l = [] >>> for x inrange(10): ... if x%2: ... l.append(x) >>> l [1, 3, 5, 7, 9]
Ah that's too complex. What about the following version?
>>> [x for x inrange(10) if x%2] [1, 3, 5, 7, 9]
To use an if...else ternary expression, you need put the if ... else ... after x, not after range(10):
>>> [i if i%2 != 0elseNonefor i inrange(10)] [None, 1, None, 3, None, 5, None, 7, None, 9]
Have you heard about nested list comprehension? You can put two or more fors in one list comprehension. For example:
>>> [i for x in [[1, 2, 3], [4, 5, 6]] for i in x] [1, 2, 3, 4, 5, 6]
>>> [j for x in [[[1, 2], [3]], [[4, 5], [6]]] for i in x for j in i] [1, 2, 3, 4, 5, 6]
Let's talk about the first part, for x in [[1, 2, 3], [4, 5, 6]] which gives [1, 2, 3] and [4, 5, 6]. Then, for i in x gives 1, 2, 3 and 4, 5, 6.
Warning: You always need put for x in [[1, 2, 3], [4, 5, 6]]beforefor i in x:
>>> [j for j in x for x in [[1, 2, 3], [4, 5, 6]]] Traceback (most recent call last): File "<input>", line 1, in <module> NameError: name 'x'isnot defined
We also have set comprehensions, dict comprehensions, and generator expressions.
set comprehensions and list comprehensions are basically the same, but the former returns a set instead of a list:
>>> {x for x in [1, 1, 2, 3, 3, 1]} {1, 2, 3}
It's the same as:
>>> set([i for i in [1, 1, 2, 3, 3, 1]]) {1, 2, 3}
A dict comprehensionlooks like a set comprehension, but it uses {key: value for key, value in ...} or {i: i for i in ...} instead of {i for i in ...}.
There are list, dictionary, and set comprehensions, but no tuple comprehensions (though do explore "generator expressions").
They address the problem that traditional loops in Python are statements (don't return anything) not expressions which return a value.
They are not the solution to every problem and can be rewritten as traditional loops. They become awkward when state needs to be maintained & updated between iterations.
but can be twisted in lots of interesting and bizarre ways.
They can be analogous to the traditional map() and filter() operations which still exist in Python and continue to be used.
When done well, they have a high satisfaction quotient.
Ответ 3
If you prefer a more visual way of figuring out what's going on then maybe this will help:
# for the example in the question...
y = [] for x inrange(10): y += [x**2]
# is equivalent to...
y = [x**2for x inrange(10)]
# for a slightly more complex example, it is useful # to visualize where the various x's end up...
a = [1,2,3,4] b = [3,4,5,6] c = []
for x in a: if x in b: c += [x] # \ \ / # \ _____\______/ # \ / \ # \/ \ # /\ \ # / \ \ # / \ \ c = [x for x in a if x in b]
print(c)
...produces the output [3, 4]
Ответ 4
I've seen a lot of confusion lately (on other SO questions and from coworkers) about how list comprehensions work. A wee bit of math education can help with why the syntax is like this, and what list comprehensions really mean.
The syntax
It's best to think of list comprehensions as predicates over a set/collection, like we would in mathematics by using set builder notation. The notation actually feels pretty natural to me, because I hold an undergrad degree in Mathematics. But forget about me, Guido van Rossum (inventor of Python) holds a masters in Mathematics and has a math background.
Set builder notation crash course
Here's the (very basics) of how set builder notation works:
So, this set builder notation represents the set of numbers that are strictly positive (i.e. [1,2,3,4,...]).
Points of confusion
1) Фильтр предикатов в нотации set builder указывает только, какие элементы мы хотим сохранить, и предикаты понимания списка делают то же самое. Вам не нужно включать специальную логику для пропуска элементов, они опущены, если не включены в предикат. Пустой предикат (т. Е. Без условия в конце) включает все элементы в данной коллекции.
2) Фильтр предикатов в нотации set builder идет в конце, и аналогично в понимании списка. (некоторые) новички думают, что что-то вроде [x < 5 for x in range(10)] даст им список [0,1,2,3,4], когда на самом деле это выводит [True, True, True, True, True, False, False, False, False, False]. Мы получаем выходные данные, [True, True, True, True, True, False, False, False, False, False] потому что мы попросили Python оценить x < 5 для всех элементов в range(10). Отсутствие предиката подразумевает, что мы получаем все из набора (точно так же, как в нотации set builder).
Если вы держите нотацию set builder в глубине своего сознания при использовании понимания списка, их немного легче усвоить.