I have a problem with the loop in python. I want create a list x[X0,X1,....Xn], with this algorithm:
X1=X0-(5+X0*2); X2=X1-(5+X1*2);.....
I try this but the result is not correct.
a=list(np.empty(10))
a[0]=1
for i in range(10):
a.append(a[i]-(5+a[i]*2))
print (a [i])
If you manually iterating the result gives:
[1,-6,1,-6, ....]
But after loop it gives:
[1,-1.29074375768e-231,2.19254982219e-314,.....]
The loop are easy in C but I did not understand the functioning in Python, if you have an idea ?
The problem is that list(np.empty(10)) doesn't do what you think it does. You expect it to return a list with 10 zeros, but it actually returns a list of 10 "random" numbers (actually, it returns a list of 10 uninitialized values).
From numpy docs:
empty, unlike zeros, does not set the array values to zero, and may
therefore be marginally faster. On the other hand, it requires the
user to manually set all the values in the array, and should be used
with caution.
(emphasize mine)
Instead, you should simply create a list with a single element, 1, and go on from there:
a = [1]
for i in range(10):
a.append(a[i] - (5 + a[i] * 2))
print(a)
# [1, -6, 1, -6, 1, -6, 1, -6, 1, -6, 1]
There's no reason to start your list with anything more than the single element. In C, you have to decide up front how many elements you want in your list, but that's not the case in Python, so doing list(np.empty(10)) creates a list with ten pointless elements in it that are just getting in your way.
a = [1] # This creates a list that starts off with the element 1.
for i in range(10):
a.append(a[i] - (5 + a[i] * 2))
print (a[i])
They way you have arranged your equation will constantly print out -6, and 1, therefore:
a = [1]
iti = 0
while(True):
thing = a[iti]-(5+(a[iti]*2))
a.append(thing)
iti+=1
print(thing)
I chose not to use the for loop to show a more understandable example, but you can still use that if you like.
I suggest you read up on functions, lists and for loops in python, as from your question it appears that you do not understand them very well.
There are several reasons why your code isn't currently working, but they are all easy fixed.
Firstly, you initiate a list with a numpy list, which is unnecessary.
a = list(np.empty(10))
can simply become
a = list()
or even simpler,
a = []
Next up, not an error but a suggestion,
a[0] = 1
can be removed and instead when you initialize the list, place one as the first item
a = [1]
after that, your code should work. So in summary:
n = 10 # or whatever number you want
a = [1]
for i in range(n - 1):
a.append(a[i] - (5 + a[i] * 2))
and if you want it as a function:
def formula_list(n):
a = [1]
for i in range(n - 1):
a.append(a[i] - (5 + a[i] * 2))
return a
Related
So i have made a list and i am trying to switch the positions of values in my list without writing the long code that i have commented out:
list = [23,5,3,1,34,5]
print(list)
#list[0],list[5] = list[5],list[0]
l = len(list)
for i in range( 1 // 2 ):
list[i],list[l-i-1] = list[l-i-1],list[i]
print(list)
when i run my code it prints the same list in the same order. How can i code it in a way that the values are switched without writing long tedious code?
for i in range( 1 // 2 ): <-- that is the number 1, not the letter l. You need to use more clear names for your variables. You actually don't need to use l in your indexing because list[-x] == list[len(list) - x] for all 1 <= x <= len(list).
lst = [23,5,3,1,34,5]
for index in range( len(lst) // 2 ):
lst[index], lst[-index-1] = lst[-index-1], lst[index]
print(lst)
FHTMichell's answer fixes your code, but if you want to just reverse the list, there are two easier methods:
lst[::-1]
or:
lst.reverse()
which both give:
[5, 34, 1, 3, 5, 23]
why?
The .reverse method is just built-in to the list object and the [::-1] slice takes advantage of the slice syntax:
[start : stop : step]
so if we leave start and stop to take their defaults (ends of the list) and set step to -1, then we get the list in reverse!
I apologize if this question has been answered already, but having programming for only a month or so, I was unable to identify an answer as it relates to my particular circumstance.
I will be taking slices from a list, and as I am taking slices from this list through a loop process, I want a particular variable that is assigned to the slices to change its name during each loop process so that I can randomly choose from these variables. So far I have been unable with my limited knowledge to come up with a way to change this variable's name (even something like x1, x2, x3 would be okay with me).
for i in range(30):
z = 0
measureList = [C4, D4, E4]
z = len(measureList)
a = measureList[x:x + z]
x = x + z
If I understand you correctly (which is highly unlikely), you'd like to access slices of a list starting at a random index to the end of the list.
Try this:
import random
my_list = [1, 2, 3, 4, 5]
n = len(my_list)
for _ in xrange(30):
start = random.randint(1, n-2)
a = my_list[start:]
Update
The problem I am having it that when I want to store these created melodies (basically slices from a list), usually a static variable will constantly overwrite the information contained in the melody that was generated in the previous pass of the loop.
I presume the "static variable" you're referring to is a. You can just store it in another list. This way you can access it after leaving the loop.
import random
my_list = [1, 2, 3, 4, 5]
n = len(my_list)
other_list = []
for _ in xrange(30):
start = random.randint(1, n-2)
a = my_list[start:]
other_list.append(a)
I'm new to python and trying to run a function that will, given one variable, count down to zero and then up to the original variable. the output should look something like this:
>>> functionname(5)
5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5
so far I've written the code below, but this doesn't count up all the way to the original variable. I guess I need to somehow save the variable in order to refer to it later, but I have no idea how to do that, since python automatically changes n as the function goes on.
def functionname(n):
n = orginal
while n > 0:
print n
n=n-1
print n
if n==0:
print n
n=n+1
I would be very grateful for some pointers, as I seem to be completely stuck at the moment.
Just count from negative to positive and use math:
def fn(n):
print ', '.join(str(abs(i)) for i in range(-n, n+1))
fn(5)
# 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5
Pointers:
If you already know the range you want to iterate over, it's much cleaner and more direct to use a for loop instead of a while.
You can use the range function to generate number sequences.
You can convert simple for loops into list-comprehensions as I did above.
The "simple" clean implementation of your requirements would look something like this:
def fn(n):
for i in range(n, 0, -1):
print i,
for i in range(n + 1):
print i,
Other notes:
range can count backwards too
The end argument to range isn't included in the range itself, that's why the second loop specifies n + 1 as the limit (instead of just n)
Adding a trailing comma on your print makes it add a space at the end instead of a line-break.
Your second block is an if n == 0: (which you know it is since the while loop terminated when n hit 0); presumably you want while n <= 5.
Note that there are nicer ways to accomplish the same thing in Python. For example, using a pair of ranges with itertools.chain to iterate each range one after another allows you to simplify to:
import itertools
def functionname(n):
for i in itertools.chain(range(n, 0, -1), range(n+1)):
print i
Personally, I'd do something like...
def count(n):
for x in range(n, -n, -1):
print(str(abs(x)) + ",")
At the suggestion of dlewin, here's a list comprehension of the same...
def count(n):
print(','.join(str(abs(x)) for x in range(n, -n, -1)))
You need a second while loop that starts at 0 and goes back up to "original".
Do you know about "for" loops yet? Those are better for counting.
Your idea about having original is correct however you are using the assignment operator the wrong way 'round. Also the if n==0 line should be another loop (while or for as suggested by other answers), counting back up to original.
So I'd start with copying the value from n to original like this:
original = n
Hope that helps!
You got some bad formatting there. Remember to indent properly for functions and while and if statements.
So first, set n to 5. Then count down from there until you reach 0 with a while loop:
while n != -1:
print n
n -= 1
Then after the loop breaks, count back up again and reset n to 0:
n = 0
while n < 6:
print n
n += 1
This question already has answers here:
Some built-in to pad a list in python
(14 answers)
Closed 8 years ago.
My goal is to take a list of unknown number of elements and extend/slice it to exactly n elements, padding lists that are too short with 0 and slicing lists that are too long.
For example
n = 10
foo = [1,2,3,4]
print some_func(foo,n)
should return [1,2,3,4,0,0,0,0,0,0], and
n = 10
foo = [1,2,3,4,5,6,7,8,9,10,11,12]
print some_func(foo,n)
should return [1,2,3,4,5,6,7,8,9,10]
Right now I'm doing this:
def some_function(l, n):
l.extend([0] * n)
l = l[:n]
return l
But that seems inefficient. Is there a more pythonic way of doing this?
EDIT: point of clarification, I am not trying to modify the original array, I am returning a new array that can be a shallow copy.
The only potentially "more Pythonic" way to do this is pretty much the way you have it, but skip over the extra variable allocation and just return the result directly. You could also definitely make it more Pythonic by conforming to PEP8 with your function and variable names.
Besides that, you can improve your efficiency by adding only as many zeroes as you need, rather than building a too-long list and then trimming it.
def pad_or_truncate(some_list, target_len):
return some_list[:target_len] + [0]*(target_len - len(some_list))
Breaking it down, there are two cases represented here (discounting the trivial case where the input is exactly the right length already). Either the list is too long, or the list is too short.
If the list is too long, we just slice it. some_list[:target_len] takes care of that. Because the slice operation is friendly, this won't blow up if the target length is beyond the actual length of the list.
If the list is too short, we pad it with zeroes. I chose to do this by multiplying a list literal1, but you can use a list comprehension the exact same way2 if that's more your cup of tea. Just determine how many zeroes to add (either zero, if the list isn't too short, or target_len - len(some_list)), and concatenate a list composed of that many zeroes. Done and done!
If you want to make it an in-place operation (as your original example appears to be trying but failing to achieve; see #chepner's comment), you would just change return <...> to some_list[:] = <...>.
1Some brief timeit results indicated that literal multiplication is a bit quicker than the double-iteration implied by a list comprehension.
2For posterity, the list comprehension version would look something like:
return some_list[:target_len] + [0 for _ in range(target_len - len(some_list))]
It is quite inefficient to build the list bigger than you need it (particularly if n gets large); instead, only add the padding you need. Also, it is Python convention to return None if a function changes its argument(s) in-place:
def some_func(l, n, pad=0):
if len(l) >= n:
del l[n:]
else:
l.extend([pad] * (n - len(l)))
Example:
>>> l = [1, 2, 3, 4, 5]
>>> some_func(l, 3)
>>> l
[1, 2, 3]
>>> some_func(l, 5)
>>> l
[1, 2, 3, 0, 0]
Alternatively, return a new list:
def some_func(l, n, pad=0):
if len(l) >= n:
return l[:n]
return l + ([pad] * (n - len(l)))
How about islice-ing the concatenation of the original list with a padding generator?
from itertools import islice, repeat
def fit_to_size(l, n):
return list(islice(
( x
for itr in (l, repeat(0))
for x in itr ),
n))
You might prefer this slightly more explicit implementation:
def fit_to_size(l, n):
def gen():
yield from l
while True: yield 0
return list(islice(gen(), n))
Why not use conditional logic?
def pad_or_slice(L, n):
if len(L) < n:
return L + ([0] * (n - len(L)))
else:
return L[:n]
This way you're only doing one of the two, not both, at the cost of checking the length of the list, which shouldn't be too costly.
It's not significantly more efficient, but I'd do l = (l + [0] * (n - len(l)))[:n]. So your some_function would look like this
def some_function(list, n):
return (list + [0] * (n - len(list)))[:n]
In order to properly modify the original list, you'll need to delete a trailing slice from the object.
def some_function(l, n):
l.extend([0] * n)
del l[n:]
Can I replace while loop with range function. I am using following code
check = 0
while check<5:
print check
check+=2
I am writing in following way
for _check in range(0,5,2):
print _check
is it correct way?
> Editing My question
if I am not using _check variable inside for loop. Can I avoid to declare also
Yes, you are using range() correctly, but you may want to use xrange() instead here:
for check in xrange(0, 5, 2):
print check
xrange() produces the same results when iterated over, but doesn't build a whole list of all possible indices first, and as a result uses less memory:
>>> range(0, 5, 2)
[0, 2, 4]
>>> xrange(0, 5, 2)
xrange(0, 6, 2)
Since the end-point is not included in the values, it doesn't matter if you use 5 or 6 here as the endpoint, it is just calculated for you from the input parameters.
If you are not using the loop variable, you can use _ to indicate that you are ignoring it in the loop. This is just a naming convention:
for _ in xrange(0, 5, 2):
# do something 3 times.
in which case you may as well just calculate how many indices there are between 0 and 5 with a step of two and simplify your loop to:
upper_limit, step = 5, 2
for _ in xrange((upper_limit - 1 + step) // step):
# do something 3 times.
Regarding the original while loop, using check = check + 1
for x in xrange(5):
print x
See the documentation here for more information on control flow tools (like loops).
EDIT
If you want to increment by 2 during each iteration, you can use the above code with the increment specified:
for x in xrange(0,5,2):
print x