forked from trekhleb/learn-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_for.py
134 lines (99 loc) · 5.06 KB
/
test_for.py
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""FOR statement
@see: https://docs.python.org/3/tutorial/controlflow.html
The for statement in Python differs a bit from what you may be used to in C or Pascal.
Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or
giving the user the ability to define both the iteration step and halting condition (as C),
Python’s for statement iterates over the items of any sequence (a list or a string), in the
order that they appear in the sequence. For example (no pun intended):
"""
# pylint: disable=too-many-locals
def test_for_statement():
"""FOR statement"""
# Measure some strings:
words = ['cat', 'window', 'defenestrate']
words_length = 0
for word in words:
words_length += len(word)
# "cat" length is 3
# "window" length is 6
# "defenestrate" length is 12
assert words_length == (3 + 6 + 12)
# If you need to modify the sequence you are iterating over while inside the loop
# (for example to duplicate selected items), it is recommended that you first make a copy.
# Iterating over a sequence does not implicitly make a copy. The slice notation makes this
# especially convenient:
for word in words[:]: # Loop over a slice copy of the entire list.
if len(word) > 6:
words.insert(0, word)
# Otherwise with for w in words:, the example would attempt to create an infinite list,
# inserting defenestrate over and over again.
assert words == ['defenestrate', 'cat', 'window', 'defenestrate']
# If you do need to iterate over a sequence of numbers, the built-in function range() comes in
# handy. It generates arithmetic progressions:
iterated_numbers = []
for number in range(5):
iterated_numbers.append(number)
assert iterated_numbers == [0, 1, 2, 3, 4]
# To iterate over the indices of a sequence, you can combine range() and len() as follows:
words = ['Mary', 'had', 'a', 'little', 'lamb']
concatenated_string = ''
# pylint: disable=consider-using-enumerate
for word_index in range(len(words)):
concatenated_string += words[word_index] + ' '
assert concatenated_string == 'Mary had a little lamb '
# Or simply use enumerate().
concatenated_string = ''
for word_index, word in enumerate(words):
concatenated_string += word + ' '
assert concatenated_string == 'Mary had a little lamb '
# When looping through dictionaries, the key and corresponding value can be retrieved at the
# same time using the items() method.
knights_names = []
knights_properties = []
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for key, value in knights.items():
knights_names.append(key)
knights_properties.append(value)
assert knights_names == ['gallahad', 'robin']
assert knights_properties == ['the pure', 'the brave']
# When looping through a sequence, the position index and corresponding value can be retrieved
# at the same time using the enumerate() function
indices = []
values = []
for index, value in enumerate(['tic', 'tac', 'toe']):
indices.append(index)
values.append(value)
assert indices == [0, 1, 2]
assert values == ['tic', 'tac', 'toe']
# To loop over two or more sequences at the same time, the entries can be paired with
# the zip() function.
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
combinations = []
for question, answer in zip(questions, answers):
combinations.append('What is your {0}? It is {1}.'.format(question, answer))
assert combinations == [
'What is your name? It is lancelot.',
'What is your quest? It is the holy grail.',
'What is your favorite color? It is blue.',
]
def test_range_function():
"""Range function
If you do need to iterate over a sequence of numbers, the built-in function range() comes in
handy. It generates arithmetic progressions.
In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t.
It is an object which returns the successive items of the desired sequence when you iterate
over it, but it doesn’t really make the list, thus saving space.
We say such an object is iterable, that is, suitable as a target for functions and constructs
that expect something from which they can obtain successive items until the supply is exhausted.
We have seen that the for statement is such an iterator. The function list() is another; it
creates lists from iterables:
"""
assert list(range(5)) == [0, 1, 2, 3, 4]
# The given end point is never part of the generated sequence; range(10) generates 10 values,
# the legal indices for items of a sequence of length 10. It is possible to let the range start
# at another number, or to specify a different increment (even negative; sometimes this is
# called the ‘step’):
assert list(range(5, 10)) == [5, 6, 7, 8, 9]
assert list(range(0, 10, 3)) == [0, 3, 6, 9]
assert list(range(-10, -100, -30)) == [-10, -40, -70]