-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathList_Comprehension
62 lines (48 loc) · 3.67 KB
/
List_Comprehension
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
List comprehension трудно перевести правильно на русский, потому, раз он генерирует новый список, будем называть его просто генератором списков. Это одна из самых приятных вещей в python, научившись писать которую, будешь применять её везде. Как это выглядит? Пожалуй Вы точно видели записи такого вида:
squares = [x ** 2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
это и есть генератор списка, результатом которого будет список квадратов последовательности 0..9. Что здесь происходит? Это обычный цикл for, только записан в удобочитаемом виде, в развёрнутом виде это выглядело бы так:
squares = []
for x in range(10):
squares.append(x ** 2)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Вот тут и видна разница в этих записях — генератор списка условно можно назвать синтаксическим сахаром для цикла for, но у них разное время выполнения. Под капотом генератор списка также использует цикл for но выигрывает по скорости из-за того, то не вызывает метод append у списка (подробности здесь).
Так же как и в обычных циклах в генераторах можно применять условия:
>>> odds = [x for x in range(10) if x % 2 != 0]
# [1, 3, 5, 7, 9]
если в условии нужен else, то всё условие пишется до for:
>>> [x ** 2 if x % 2 == 0 else x ** 3 for x in range(10)]
# [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]
Гораздо удобнее итерироваться по двум спискам:
first = []
for x in range(1, 5):
for y in range(5, 1, -1):
if x != y:
first.append((x, y))
second = [(x, y) for x in range(1, 5) for y in range(5, 1, -1) if x != y]
>>> first == second
True
Отличный пример из документации (раскрытие списка списков), усложним его:
>>> vec = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]]
>>> [digit for lst in vec for elem in lst for digit in elem]
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Подобным образом с помощью генераторов списков мы можем создать словарь:
>>> dict([(key, value) for (key, value) in zip([1, 2, 3], ['a', 'b', 'c'])])
# {1: 'a', 2: 'b', 3: 'c'}
И тут нас ожидает приятная новость — в python есть и генераторы словарей, записываются так же, как и генераторы списков, только в фигурных скобках { ... }:
>>> {key: value for key, value in zip([1, 2, 3], ['a', 'b', 'c'])}
# {1: 'a', 2: 'b', 3: 'c'}
К слову, словарь можно создать и без генератора — dict(zip(list1, list2)).
Если мы генератор списка запишем в круглых скобках, то получим обычный генератор:
>>> gen = (x for x in range(10))
>>> gen
<generator object <genexpr> at 0x7f635076ea98>
>>> gen.__next__()
0
>>> gen.__next__()
1
d = (4,2,3)
print(s[round(len(s))-1])
d = (1,) + d[1:]
print(d)
.......