How do you convert a c-style for loop into python?
for (int i = m; i >= lowest; i--)
The best that I came up with was:
i = mid
for i in range(i, low,-1):
for i in range(m, low - 1, -1):
Keep in mind range is exclusive of the stop parameter.
range(...)
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
The difference between this code and the C code is that in Python 2, a list is being constructed in memory by range so for very huge ranges this could be a problem. Replacing range with xrange would not build a list in memory and make the code practically the same. In Python 3 this issue no longer exists.
m from where the loop start.
l where the loop stop, and range exclude last item so l-1 and
-1 for reverse array.
for i in range(m, l-1, -1):
m = 20
low = 10
for i in range(m, low - 1, -1):
print i
This will count down as expected:
20
19
18
17
16
15
14
13
12
11
10
range takes three parameters, a start, a stop and the increment between each step.
Where possible, the Python idiom is to loop over the items directly, not to count through them. Therefore an idiomatic way to count down would be for item in reversed(list): print item or to take a reversed slice >>> someList[m:lowest-1:-1]
If you are looping over items and also need a counter, Python has enumerate() to generate counting index numbers while looping. for index, value in enumerate(someList):
It's not always possible to do this, sometimes you are counting and not going over any other data except the numbers, and range() is fine - as the other answers suggest. But when you have a for (int i=... loop, see if you can change it to act directly on the data. Writing "C in Python" is no fun for anyone.
Related
I am sorry if the title is a misnomer and/or doesn't properly describe what this is all about, you are welcome to edit the title to make it clear once you understand what this is about.
The thing is very simple, but I find it hard to describe, this thing is sorta like a number system, except it is about lists of integers.
So we start with a list of integers with only zero, foreach iteration we add one to it, until a certain limit is reached, then we insert 1 at the start of the list, and set the second element to 0, then iterate over the second element until the limit is reached again, then we add 1 to the first element and set the second element 0, and when the first element reaches the limit, insert another element with value of 1 to the start of the list, and zero the two elements after it, et cetera.
And just like this, when a place reaches limit, zero the place and the places after it, increase the place before it by one, and when all available places reach limit, add 1 to the left, for example:
0
1
2
1, 0
1, 1
1, 2
2, 0
2, 1
2, 2
1, 0, 0
The limit doesn't have to be three.
This is what I currently have that does something similar to this:
array = []
for c in range(26):
for b in range(26):
for a in range(26):
array.append((c, b, a))
I don't want leading zeroes but I can remove them, but I can't figure out how to do this with a variable number of elements.
What I want is a function that takes two arguments, limit (or base) and number of tuples to be returned, and returns the first n such tuples in order.
This must be very simple, but I just can't figure it out, and Google returns completely irrelevant results, so I am asking for help here.
How can this be done? Any help will truly be appreciated!
Hmm, I was thinking about something like this, but very unfortunately I can't make it work, please help me figure out why it doesn't work and how to make it work:
array = []
numbers = [0]
for i in range(1000):
numbers[-1] += 1
while 26 in numbers:
index = numbers.index(26)
numbers[index:] = [0] * (len(numbers) - index)
if index != 0:
numbers[index - 1] += 1
else:
numbers.insert(0, 1)
array.append(numbers)
I don't quite understand it, my testing shows everything inside the loop work perfectly fine outside the loop, the results are correct, but it just simply magically will not work in a loop, I don't know the reason for this, it is very strange.
I discovered the fact that if I change the last line to print(numbers) then everything prints correctly, but if I use append only the last element will be added, how so?
from math import log
def number_to_base(n,base):
number=[]
for digit in range(int(log(n+0.500001,base)),-1,-1):
number.append(n//base**digit%base)
return number
def first_numbers_in_base(n,base):
numbers=[]
for i in range(n):
numbers.append(tuple(number_to_base(i,base)))
return numbers
#tests:
print(first_numbers_in_base(10,3))
print(number_to_base(1048,10))
print(number_to_base(int("10201122110212",3),3))
print(first_numbers_in_base(25,10))
I finally did it!
The logic is very simple, but the hard part is to figure out why it won't work in a loop, turns out I need to use .copy(), because for whatever reason, doing an in-place modification to a list directly modifies the data reside in its memory space, such behavior modifies the same memory space, and .append() method always appends the latest data in a memory space.
So here is the code:
def steps(base, num):
array = []
numbers = [0]
for i in range(num):
copy = numbers.copy()
copy[-1] += 1
while base in copy:
index = copy.index(base)
copy[index:] = [0] * (len(copy) - index)
if index != 0:
copy[index - 1] += 1
else:
copy.insert(0, 1)
array.append(copy)
numbers = copy
return array
Use it like this:
steps(26, 1000)
For the first 1000 lists in base 26.
Here is a a function, that will satisfy original requirements (returns list of tuples, first tuple represents 0) and is faster than other functions that have been posted to this thread:
def first_numbers_in_base(n,base):
if n<2:
if n:
return [(0,)]
return []
numbers=[(0,),(1,)]
base-=1
l=-1
num=[1]
for i in range(n-2):
if num[-1]==base:
num[-1]=0
for i in range(l,-1,-1):
if num[i]==base:
num[i]=0
else:
num[i]+=1
break
else:
num=[1]+num
l+=1
else:
num[-1]+=1
numbers.append(tuple(num))#replace tuple(num) with num.copy() if you want resutl to contain lists instead of tuples.
return numbers
I am trying to convert the below for loop to Python.
for (i = 5; i < n; i = i*5):
I am not sure how to make use of the Range function when i want the i value to be set to the multiple of 5. For example, 1st time I want the i to be 5, then followed by 25, then followed by 125 and it should go on.
The following is what i have tried:
i = 5
for i in range (i, n+1, i*5)
The problem with the above being, the value of i getting incremented by 25, making it to 30 whereas i want the i to be 25 in the second iteration. It is pretty easy when using the while loop. But I am seeing if there is a way to implement the same in the for loop. Please help. Thanks in advance.
I am not sure how to make use of the Range function when i want the i value to be set to the multiple of 5
It will not work that way. range can only create arithmetic sequences; multiplying every time creates a geometric sequence.
What you can do is take advantage of the fact that the i values are successive powers of 5; so make a loop over the desired exponent values, and compute i inside the loop:
# Computing the `limit` in terms of `n` is left as an exercise.
# Just in case you were already computing `n` in terms of an existing `limit`,
# in which case you could just use it directly ;)
for j in range(limit):
i = 5**j
There is a theorem in computer science that states that any "C-style" for loop can be transformed into an equivalent while loop. This is one of those cases where the transformation is desirable:
i = 5
while i < n:
# Loop body goes here
i *= 5
You can hide the loop logic behind a generator:
def multrange(start, stop, ratstep):
i = start
while i < stop:
yield i
i *= ratstep
list(multrange(5, 10000, 5))
#[5, 25, 125, 625, 3125]
You can define your own range function using yield!
def range(i, j, k):
while i * k < j:
i *= k
yield i
for i in range(5, 2000, 5):
print(i)
Output:
25
125
625
Most Python programmers would just use a while loop:
i = 5
while i < n:
....
i = i * 5
If you really, really want a for loop:
import itertools
for i in itertools.takewhile(lambda x: x < n, (5 ** i for i in itertools.count(1))):
... whatever ...
I need to create an List of size N and then initialize only N-1th and N-2th elements only. Which means if the size of the list is 5 then it should only contain elements in 3rd and 4th position.
i know how to do it in C++ but is there any way to implement it in Python?
for example: In C++
int *n = new int[5];
n[3] = 20
n[4] = 10
//and if we print the output it will show some garbage values in index 0, 1, 2 and will print 20 10 which is the values we initailized
How can i do it in python? or anything similar to this!
In python, list must be initialized with values.
Closest thing you can do:
N = 5
lst = [0] * (N-2) + [20, 10]
This:
Fills the N-2 elements of a list with default value 0
Sets the value for the last two elements
Concatenates the zeros and last two elements sub-lists of stages 1 & 2
In python,
array=[]
length=5
for i in range(length):
array.append(0)
array[3]=20
array[4]=10
Edit: As pointed out by kabanus, a more efficient way to do this would be-
array=[0]*length
Instead of the for loop.
How to loop multiple variables and different steps parallel?
Like, in c++, for(int i=0, j=n-1; i<n && j>=0; i++, j--).
You can use the built-in function zip() to iterate multiple iterables in parallel:
for i,j in zip(range(n), range(n-1, -1, -1)):
print(i, j)
Possible output:
0 9
1 8
2 7
3 6
4 5
5 4
6 3
7 2
8 1
9 0
zip() will stop iteration once the first iterator is exhausted. When you want to continue until the last is done, providing fill values for the others, you can use itertools.zip_longest().
For reference:
https://docs.python.org/3/library/functions.html#zip
https://docs.python.org/3/library/itertools.html#itertools.zip_longest
In Python, for loops are usually iterated over a sequence (such as but not limited to: a list, numpy array, a range, enumerated type, dict items etc).
The below implementation is a zip'd form of two range objects:
for i, j in zip(range(0, n, 1), range(n-1, -1, -1)):
print(i, j)
The limitation in this approach is that the two sequences (one over i and one over j must be of the same length.
However, if say i iterates over n elements and j over m elements, then the number of times the loop will be executed will be min(i, j), i.e., the execution exits the loop as soon as one of the sequences is completed.
I am having a big list of items (and the list may sometimes hold 1 million items). Now I want to filter elements in this list based on the length of each item. i.e. I want to add items which are either less than 7 chars or greater than 24 chars. The code which I wrote is:
returnNumbers //the list that holds million items
for num in returnNumbers:
if((len(num)<7 or len(num)>24)):
invalidLengthNumbers.append(num);
Not sure if there is a better way of doing this, as going thru 1 million items is time taking.
You want to take an iterative approach, really.
Your code can be replaced with a list comprehension:
invalidLengthNumbers = [num for num in returnNumbers if len(num) < 7 or len(num) > 24]
or, shorter and only taking one len() call by taking advantage of comparison chaining:
invalidLengthNumbers = [num for num in returnNumbers if not 7 <= len(num) <= 24]
but that'll only be marginally faster.
If you need to loop over invalidLengthNumbers later, don't use an intermediary list. Loop and filter over returnNumbers directly. Perhaps even returnNumbers itself can be replaced by a generator, and filtering that generator can be done iteratively too.
def produceReturnNumbers():
for somevalue in someprocess:
yield some_other_value_based_on_somevalue
from itertools import ifilter
for invalid in ifilter(lambda n: not 7 <= len(n) <= 24, produceReturnNumbers()):
# do something with invalid
Now you no longer have a list of 1 million items. You have a generator that will produce 1 million items as needed without holding it all in memory.