Cycle "for" in python like in C [duplicate] - python

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python decimal range() step value
I have a cycle in C:
for (float i = 0; i < 2 * CONST; i += 0.01) {
// ... do something
}
I need the same cycle in python, but:
for x in xxx
not the same.
How can i make it in python?

You are almost on the line. This is how you do it on a list: -
your_list = [1, 2, 3]
for eachItem in your_list:
print eachItem
If you want to iterate over a certain range: -
for i in xrange(10):
print i
To give a step value you can use a third parameter, so in your case it would be: -
for i in xrange(2 * CONST, 1):
print i
But you can only give an integer value as step value.
If you want to use float increment, you would have to modify your range a little bit:-
for i in xrange(200 * CONST):
print i / 100.0

for i in xrange(200*CONST):
i = i/100.0

Write your own range generator. This helps you deal with non-integer step values with ease, all across your program, solving multiple issues of the same kind. It also is more readable.
def my_range(start, end, step):
while start <= end:
yield start
start += step
for x in my_range(1, 2 * CONST, 0.01):
#do something
For-loop reference

numpy has a method that can be used to create a range of floats.
from numpy import arange
for x in arange(0, 2*CONST, 0.01):
do_something(x)

Related

How to improve efficiency and time-complexity of AIO Cloud Cover solution

Sorry for the noob question, but is there a less time expensive method to iterate through the input list, as upon submission I receive timeout errors. I tried changing the method of checking for the minimum answer by appending to a list and using min function, but as expected that didn't help at all.
Input:
6 3
3
6
4
2
5
Solution:
with open("cloudin.txt", "r") as input_file:
n, covered = map(int, input_file.readline().split())
ls = [None for i in range(100005)]
for i in range(n-1):
ls[i] = int(input_file.readline().strip())
ans = 1000000001
file = open("cloudout.txt", "w")
for i in range(n-covered):
a = 0
for j in range(covered):
a += ls[i+j]
if a < ans:
ans = a
file.write(str(ans))
output:
11
https://orac2.info/problem/aio18cloud/
Note: Blue + White indicates timeout
The core logic of your code is contained in these lines:
ans = 1000000001
for i in range(n-covered):
a = 0
for j in range(covered):
a += ls[i+j]
if a < ans:
ans = a
Let's break down what this code actually does. For each closed interval (i.e. including the endpoints) [left, right] from the list [0, covered-1], [1, covered], [2, covered+1], ..., [n-covered-1, n-2] (that is, all closed intervals containing exactly covered elements and that are subintervals of [0, n-2]), you are computing the range sum ls[left] + ls[left+1] + ... + ls[right]. Then you set ans to the minimum such range sum.
Currently, that nested loop takes O((n-covered)*covered)) steps, which is O(n^2) if covered is n/2, for example. You want a way to compute that range sum in constant time, eliminating the nested loop, to make the runtime O(n).
The easiest way to do this is with a prefix sum array. In Python, itertools.accumulate() is the standard/simplest way to generate those. To see how this helps:
Original Sum: ls[left] + ls[left+1] + ... + ls[right]
can be rewritten as the difference of prefix sums
(ls[0] + ls[1] + ... + ls[right])
- (ls[0] + ls[1] + ... + ls[left-1])
which is prefix_sum(0, right) - prefix_sum(0, left-1)
where are intervals are written in inclusive notation.
Pulling this into a separate range_sum() function, you can rewrite the original core logic block as:
prefix_sums = list(itertools.accumulate(ls, initial=0))
def range_sum(left: int, right: int) -> int:
"""Given indices left and right, returns the sum of values of
ls in the inclusive interval [left, right].
Equivalent to sum(ls[left : right+1])"""
return prefix_sums[right+1] - prefix_sums[left]
ans = 1000000001
for i in range(n - covered):
a = range_sum(left=i, right=i+covered-1)
if a < ans:
ans = a
The trickiest part of prefix sum arrays is just avoiding off-by-one errors in indexes. Notice that our prefix sum array of the length-n array ls has n+1 elements, since it starts with the empty initial prefix sum of 0, and so we add 1 to array accesses to prefix_sums compared to our formula.
Also, it's possible there may be an off-by-one error in your original code, as the value ls[n-1] is never accessed or used for anything after being set?

For Loop - Range - Python - Question on the increment logic

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 ...

How to increment a variable inside of a list comprehension

I have a python function which increments the character by 1 ascii value if the index is odd and decreases the ascii value by 1 if index is even .I want to convert it to a function which do the same increment and decrement but in the next set i want to increment by 2 and then decrement by -2 then by 3 and -3 and so on..
What Iam trying to do is to increment the counter variable by 1 each time an even index occurs after performing the ascii decrement.
I also dont want to do it with a for loop is there any way to do it in the list comprehension itself?
In my function if the input is
input :'abcd' output: is 'badc' what i want is 'baeb'
input :'cgpf' output: is 'dfqe' what i want is 'dfrd'
def changer(s):
b=list(s)
count=1
d=[chr(ord(b[i])+count) if i%2==0 else chr(ord(b[i])-count) for i in range(0,len(b))]
return ''.join(d)
I need something like count++ as show but sadly python dont support it.
def changer(s):
b=list(s)
count=1
d=[chr(ord(b[i])+count) if i%2==0 else chr(ord(b[i])-count++) for i in range(0,len(b))]
return ''.join(d)
Here is the runnable code
If I correctly understood what you're after, something like this (compact form) should do:
def changer(s):
return "".join(chr(ord(c) + ((i // 2) + 1) * (-1 if i % 2 else 1))
for i, c in enumerate(s))
We get index and character from string by means of enumerate() and use that to feed a generator comprehension (as asked for) far of index (i) and character (c) from the string.
For each ASCII value of c, we add result of integer division of i (incremented by one as index was 0 based) by 2 and multiply it by (-1 if i % 2 else 1) which flips +/- based on even/odd number: multiply by -1 when modulo of i division by 2 is non-zero (and bool() evaluates as True), otherwise use 1.
Needless to say: such comprehension is not necessarily easy to read, so if you'd use it in your script, it would deserve a good comment for future reference. ;)
Combine a stream of plus/minus with the string.
import itertools
s = 'abcdefg'
x = range(1,len(s)+1)
y = range(-1,-len(s)+1,-1)
z = itertools.chain.from_iterable(zip(x,y))
r = (n + ord(c) for (n,c) in zip(z,s))
''.join(chr(n) for n in r)
I don't think I'd try to put it all in one line. Uses generator expressions instead of list comprehensions.
Try the code below,
def changer(s):
return ''.join([chr(ord(j) + (i // 2 + 1)) if i % 2 == 0 else chr(ord(j) - (i // 2 + 1)) for i, j in enumerate(s)])
s = 'abcd'
changer(s)
output
baeb

How to use nested loops in order take integers and produce strings

I need to create a function that receives a positive integer number (n) and returns a string, using nested loops.
For example:
when n = 3 the returned string should be:
"1+2+3+..1+2+3+..1+2+3+.."
when n = 5 the returned string should be:
1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..
As an example, the following code fragment:
n = 5
res = addnestedloops(n)
print (res)
should produce the output:
1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..
Can't seem to find out how to return the string in which it counts upwards until the inputted number...
def themethod(n):
var toprint="";
var tmp;
if(n>0)tmp="1";
for(var i=2;i<=n;i++):
tmp+= "+".i;
for(var i=0;i<n;i++):
toprint += tmp;
print toprint;
I think what you are looking for is head-recursion in python
Here is the code which will let you achieve this
def recursive(n):
if n == 1:
return 1
else:
return str(recursive(n-1)) + "+"+str(n)
A nested loop is just a loop within a loop. If I understand you correctly, you need n strings concatenated, each containing n numbers.
I have a feeling this is a school assignment, so I wont give you the full answer, but I believe the nested loop construction you need is
for i in range(n):
for j in range(n):
# Construct the sub string here and append it to a result variable
Remember that the range function output is zero based, so range(3) produces 0, 1 and 2.
I don't however see why you need a nested loop, other than it should be a part of the assignment. You could just construct the sub string and repeat it n times with substring * n. For example 'hello' * 3 results in 'hellohellohello'.
Oh, and just to give you a bit more to think about, the one-liner solution for your problem is
('+'.join('{0:d}'.format(i+1) for i in range(n)) + '+..') * n

Python sorting arrays to get two digit values

I have an array A = [1 - 100] and I need to find the sum of all the two digit values in this array. How would I approach this? I have tried :
def solution(A):
A =array[0-100])
while A > 9 & A < 99
total = sum(A)
print "%s" % total
)
Is there a function that given an array consisting of N integers returns the sum of all two digit numbers i.e A = [1,1000,80, -91] the function should return -11(as the two are 80 and -91). not a range, multiple array
You can use a list comprehension and check if the length of the string-format is equal to 2, like so:
sum([x if len(str(x))==2 else 0 for x in xrange(1,101)])
Use the keyword and rather than the bitwise &.
Edit: a fuller answer, as that's not the only thing wrong:
def solution():
A = range(101)
total = sum([a for a in A if 9 < a <= 99])
print total
This uses list comprehension and chained inequalities, so is pretty 'pythonic'.
There is tons of errors in your code, please next time before posting,spend some time try to figure it out yourself and be sure that your code at lest doesn't contain any obvious syntax error.
By array, I assume you're talking about a list. And change it to range(101) for every number from 0 to 100
def solution(A):
return sum([x for x in range(A) if len(str(abs(x))) == 2])
print(solution(101))
As a side note, use and instead of & since that's a bitwise-or sign.
Here are a couple of ways to go about the problem, the first is most similar to the approach you appear to be trying:
def solution1(array):
total = 0
for a in array:
if 9 < a < 100:
total += a
return total
print(solution1(range(101)))
And here's a more compact solution using a comprehension (actually, a generator expression):
def solution2(array):
return sum(a for a in array if 9 < a < 100)
print(solution2(range(101)))
Note that in your original you're confusing loops and conditionals.

Categories

Resources