Для цикла с пользовательскими шагами в python
Я могу сделать простой для циклов в python, например:
for i in range(10):
Однако я не мог понять, как сделать более сложные, что очень просто в С++.
Как бы вы реализовали цикл for, подобный этому в python:
for(w = n; w > 1; w = w / 2)
Ближайшим, который я сделал до сих пор, является:
for w in reversed(range(len(list)))
Ответы
Ответ 1
В первую очередь: петли Python for
на самом деле не такие, как цикл C for
. Они вместо этого для каждой петли. Вы перебираете элементы итерации. range()
генерирует итерируемую последовательность целых чисел, позволяя вам эмулировать наиболее распространенный случай использования цикла C for
.
Однако большую часть времени вы не хотите использовать range()
. Вы будете перебирать сам список:
for elem in reversed(some_list):
# elem is a list value
Если вам нужен индекс, вы обычно используете enumerate()
, чтобы добавить его в цикл:
for i, elem in reversed(enumerate(some_list)):
# elem is a list value, i is it index in the list
Для действительно "забавных" циклов используйте while
или создайте собственную функцию генератора:
def halved_loop(n):
while n > 1:
yield n
n //= 2
for i in halved_loop(10):
print i
для печати 10
, 5
, 2
. Вы также можете расширить это на последовательности:
def halved_loop(sequence):
n = -1
while True:
try:
yield sequence[n]
except IndexError:
return
n *= 2
for elem in halved_loop(['foo', 'bar', 'baz', 'quu', 'spam', 'ham', 'monty', 'python']):
print elem
который печатает:
python
monty
spam
foo
Ответ 2
for i in range(0, 10, 2):
print(i)
>>> 0
>>> 2
>>> 4
>>> 6
>>> 8
http://docs.python.org/2/library/functions.html
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
Ответ 3
Для вашего точного примера вы, вероятно, не будете использовать цикл for вообще, но цикл while:
w = n
while w > 1:
do stuff
w = w / 2
Ответ 4
Вам нужно использовать генератор. Вы можете реализовать это следующим образом:
def stepDown(n):
while n>1:
yield n
n = n/2
for i in stepDown(n):
print i # or do whatever else you wish.
Обратите внимание, что это легко обобщается на другие сложные шаблоны, которые вы можете иметь в виду.
Ответ 5
Что-то вроде for i in [n/(2**j) for j in range(int(math.log(n))+1)]
Ответ 6
В более общем случае вы можете создать пользовательскую функцию генератора, которая принимает start
, stop
и функцию для создания следующего шага от последнего:
def my_range(start, stop, f):
x = start
while x < stop if stop > start else x > stop:
yield x
x = f(x)
>>> list(my_range(1, 1024, lambda x: x*2))
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
>>> list(my_range(1000, 1, lambda x: x/2))
[1000, 500.0, 250.0, 125.0, 62.5, 31.25, 15.625, 7.8125, 3.90625, 1.953125]