for loop list incrementation - python

In order to find multiples of 3 under 1000, I used this method:
a=[]
import itertools
for x in itertools.count():
while x<1000:
if x%3==0:
a.append[x]
print(a)
I'm a beginner, please help me find the error.

Why not simply
a = list(range(0, 1000, 3))
or even
a = range(0, 1000, 3)
in Python 2?

Are you coding in Python 3 ?
You are missing indentation mostly and usage of function depends on the version of Python you are using and also there are different solutions to how you can handle the iterations , which may differ to your style. I also want to point out that append method needs parentheses instead of brackets.
However i tried not to modify your code much.
You can check it on the online editor below.
https://repl.it/#Umbreon1/SpiffyAshamedPdf
import itertools
a=[]
upperLimit=1000
for x in itertools.islice(itertools.count(0),upperLimit + 1):
if x%3 == 0:
a.append(x)
print(a)

Related

applying for loop such that counters are multiplied rather than being added in python

hello I am relatively new to python! Is there a way to do this using for loops in python?
This is a java implementation of something i want to do in python
for (i=1;i<20; i*= 2)
{System.out.println(i);}
Solution in while loop in python`
while i<20:
print i
i*=2
I cannot figure out a way to do this using for loops. Implemented it using while loop obviously, but still curious to know whether there is a method to do so or not
There are lots of ways to do this, e.g.
for i in range(5):
i = 2 ** i
print i
or using generators
from itertools import count, takewhile
def powers_of_two():
for i in count():
yield 2 ** i
for i in takewhile(lambda x: x < 20, powers_of_two()):
print i
But in the end, it depends on your use case what version gives the clearest and most readbale code. In most cases, you would probably just use a while-loop, since it's simple and does the job.
You think of for loops like they would be in other languages, like C, C++, Java, JavaScript etc.
Python for loops are different; they work on iterables, and you always have to read them like:
for element in iterable
instead of the C'ish
for(start_condition; continue_condition; step_statement)
Hence, you would need iterable to generate your products.
I like readability, so here's how I'd do it:
for a in (2**i for i in range(20)):
print a
But that mainly works because we mathematically know that the i'th element of your sequence is going to be 2**i.
There is not a real way to do this in Python. If you wanted to mimic the logic of that for loop exactly, then a manual while loop would definitely be the way to go.
Otherwise, in Python, you would try to find a generator or generator expression that produces the values of i. Depending on the complexity of your post loop expression, this may require an actual function.
In your case, it’s a bit simpler because the numbers you are looking for are the following:
1 = 2 ** 0
2 = 2 ** 1
4 = 2 ** 2
8 = 2 ** 3
...
So you can generate the numbers using a generator expression (2 ** k for k in range(x)). The problem here is that you would need to specify a value x which happens to be math.floor(math.log2(20)) + 1 (because you are looking for the largest number k for which 2 ** k < 20 is true).
So the full expression would be this:
for i in (2 ** k for k in range(math.floor(math.log2(20)) + 1)):
print(i)
… which is a bit messy, so if you don’t necessarily need the i to be those values, you could move it inside the loop body:
for k in range(math.floor(math.log2(20)) + 1):
i = 2 ** k
print(i)
But this still only fits your purpose. If you wanted a “real” C-for loop expression, you could write a generator function:
def classicForLoop (init, stop, step):
i = init
while i < stop:
yield i
i = step(i)
Used like this:
for i in classicForLoop(1, 20, lambda x: x * 2):
print(i)
Of course, you could also modify the generator function to take lambdas as the first and second parameter, but it’s a bit simpler like this.
Use range() function to define iteration length.You can directly use print() than system.out.println
Alexander mentioned it and re-iterating
for i in range(1,20):print(i*2)
You can also consider while loop here-
i=0
while (i<20):
print(2**i)
i=i+1
Remember indentation in python

Accelerating for loops with list methods in Python

I have for loops in python that iterates nearly 2.5 million times and it's taking so much time to get a result. In JS I can make this happen in nearly 1 second but Python does it in 6 seconds on my computer. I must use Python in this case. Here is the code:
for i in xrange(k,p,2):
arx = process[i]
ary = process[i+1]
for j in xrange(7,-1,-1):
nx = arx + dirf[j]
ny = ary + dirg[j]
ind = ny*w+nx
if data[ind] == e[j]:
process[c]=nx
c=c+1
process[c]=ny
c=c+1
matrix[ind]=1
Here is some lists from code:
process = [None] * (11000*4) it's items will be replaced with integers after it's assignment.
dirf = [-1,0,1,-1,1,-1,0,1]
dirg = [1,1,1,0,0,-1,-1,-1]
e = [9, 8, 7, 6, 4, 3, 2, 1]
the data list is consists of 'r' informations from pixels of an rgba image.
data = imgobj.getdata(0)
How can I boost this. What am I doing wrong? Is there any other approaches about for loops? Thanks.
Here are a few suggestions for improving your code:
That inner xrange is being used a lot: what if you made that a regular list and just did something like this:
inner = range(7,-1,-1) # make the actual list
for(a,b,c): #first for
#stuff
for i in inner # reference an actual list and not the generator
Evidence :
n = range(7,-1,-1)
def one():
z = 0
for k in xrange(100):
for i in n:
z+=1
def two():
z = 0
for k in xrange(100):
for i in xrange(7,-1,-1):
z+=1
if __name__ == '__main__':
import timeit
print("one:")
print(timeit.timeit("one()",number=1000000 ,setup="from __main__ import one"))
print("two:")
print(timeit.timeit("two()",number=1000000 ,setup="from __main__ import two"))
"result"
one:
37.798637867
two:
63.5098838806
If the code I wrote is comparable, it would appear to indicate that referencing the inner list and not generating really speeds it up.
[edit] referencing local variable is faster than accessing global.
so if this is correct place the list definition as close to the loop as possible without having it generate every time.
You are also changing process twice. If it's not needed, just choose one.
As you mentioned in the comments, you say you're working with images. I am not sure if the following is relevant, but perhaps you could use openCV, which has a Python API to C code. That might speed it up. As others have mentioned: numpy and your own cython extensions will speed this up considerably.

Is there a built-in function for creating a list of random numbers of size 'n'?

The standard way of creating a list of random numbers is:
def generateList(n):
randlist = []
for i in range(n):
randlist.append(random.randint(1,9))
return randlist
However, I recently stumbled upon random.sample, which is much more compact:
def generateList(n):
return random.sample(range(1, 10), n)
But this results in an error if n is greater than 10. So, my question is, does there exist a built-in function that does exactly what I intend it to do without running into error? If not, is there at least a more efficient alternative to the first excerpt (considering that n can be quite large)?
No, there is not a function specifically dedicated to this task. But you can use a list comprehension if you want to condense the code:
def generateList(n):
return [randint(1, 9) for _ in range(n)]
The activity of sampling is to select a maximum of N elements from the sample space of size N. That is why you are getting an error.
Having said that, there are many efficient ways to solve your problem.
We can simply wrap your code in a list comprehension, like this
def generateList(n):
return [randint(1, 9) for i in range(n)]
Use randrange instead of randint, like this
def generateList(n):
return [randrange(1, 10) for i in range(n)]
If the number of possible elements is small, you can even use choice like this
def generateList(n, sample_space = range(1, 10)):
return [choice(sample_space) for i in range(n)]
Note: Since n is going to large, if you are using Python 2.7, use xrange instead of range. You can read more about the differences in this answer.
I think you're going to just have to sample it n times, each with size 1. The reason you are running into the error is that sample doesn't want to repeat numbers: when you ask for 12 unique numbers from a 10 element list, it chokes. Try:
def generateList(n, theList):
return [random.sample(theList, 1) for _ in range(n)]

How to count by twos with Python's 'range'

So imagine I want to go over a loop from 0 to 100, but skipping the odd numbers (so going "two by two").
for x in range(0,100):
if x%2 == 0:
print x
This fixes it. But imagine I want to do so jumping two numbers? And what about three? Isn't there a way?
Use the step argument (the last, optional):
for x in range(0, 100, 2):
print(x)
Note that if you actually want to keep the odd numbers, it becomes:
for x in range(1, 100, 2):
print(x)
Range is a very powerful feature.
(Applicable to Python <= 2.7.x only)
In some cases, if you don't want to allocate the memory to a list then you can simply use the xrange() function instead of the range() function. It will also produce the same results, but its implementation is a bit faster.
for x in xrange(0,100,2):
print x, #For printing in a line
>>> 0, 2, 4, ...., 98
Python 3 actually made range behave like xrange, which doesn't exist anymore.
for i in range(0, 100, 2):
print i
If you are using an IDE, it tells you syntax:
min, max, step(optional)

Variable assignment in expressions

Here is my code to generate values in the fibonnacci sequence below 10,000,000.
3 fibs = [1,1]
4 while((x = fibs[-1] + fibs[-2]) <= 10000000):
5 fibs.append(x)
I attempted to do C-style assignment of x in the while loop's condition. Unfortunately, python told me that it's a syntax error. What is the simplest solution?
In Python, assignment is not an expression, and therefore has no value.
The simplest solution is to do the assignment in the first part of the loop:
fibs=[1,1]
while fibs[-1] <= 10000000:
fibs.append(fibs[-1] + fibs[-2])
Basically:
fibs = [1]
x = 1
while(x <= 10000000):
fibs.append(x)
# It is not possible for "fibs" not to have
# at least two elements by now
x = fibs[-1] + fibs[-2]
(It was, in fact, one of the design goals of Python to avoid mixing expressions and assignments like C — that's why there's no x++, x--, which is also a semi-FAQ.)
The reason for not allowing assignment in Python expressions is a common, hard-to-find bug in those other languages, caused by this construct.
Please check
http://effbot.org/pyfaq/why-can-t-i-use-an-assignment-in-an-expression.htm
from functools import partial
from itertools import imap, islice, takewhile
import operator
fibs = [1, 1]
for x in takewhile(partial(operator.ge, 10000000),
imap(operator.add, fibs, islice(fibs, 1, None))):
fibs.append(x)
Oh wait, you said "simplest"? Nevermind then.

Categories