I have a list of integers and I am trying to define a function which loops through every element to check if they are less than 5 and returns the list in string according to their contents.
intlist=[12, 10, 11, 23, 25, 2]
def clear(x):
for i in x:
if i < 5:
x[i] = 0
return str(x)
else:
return str(x)
print clear(intlist)
My code is not working as intended, could anyone enlighten me?
If they are, I am to change all elements in the list to '0'. The outcome should look something like this.
intlist=[0, 0, 0, 0, 0, 0]
However if none of the elements are less than 5, the output should remain the same.
intlist=[12, 10, 11, 23, 25, 2]
Welcome to StackOverflow! Your code has some logic problem. Here's my fix:
intlist=[12, 10, 11, 23, 25, 2]
def clear(x):
for i in x:
if i < 5: # If this is satisfied once, return string with n times of '0'
x = [0]*len(x) # This creates a list of zeros with same length as before
return str(x)
return str(x)
print clear(intlist)
Besides, in your example the element 2 is less than 5, so the output should be 000000
intlist=[12, 10, 11, 23, 25, 2]
def clear(x):
if (any(i<5 for i in intlist)): return [0]*len(intlist)
else: return(x)
print(clear(intlist)) # [0, 0, 0, 0, 0, 0]
check for the any item is <5 then return all zeros or keep the list as it is.
There are a couple of mistakes in the for loop that you have written. First, the return statement is inside the loop, which makes it exit just after the if statement or else statement, whichever it goes to first. Secondly, you are making a mistake with how you are indexing. If you wish to access elements through index, you range in your loop instead. Here is the correct implementation for the function that you want :
def clear(x):
for i in range(len(x)):
if x[i]<5:
x[i]=0
return str(x)
You can do it one one-line, creating a list of zeros if any one of the elements in list is less than 5 or retaining the list otherwise.
intlist = [12, 10, 11, 23, 25, 2]
intlist = [0] * len(intlist) if any(x < 5 for x in intlist) else intlist
print(intlist)
# [0, 0, 0, 0, 0, 0]
Related
I have the following list:
listInitial = [20, 33, 24, 11, 0, 4, 3, 11]
I'm trying to write a function that iterates through it and returns a copy of this list with 11 removed. Desired output is: [20, 33, 24, 0, 4, 3]
I want to use the append method and for loop in my function. Below is my code:
listSecond = []
def iterateandremove (listInitial, num):
for i in listInitial:
if i != num:
listSecond.append(i)
print (listSecond)
return (listSecond)
iterateandremove (listInitial, 11)
When I run the code it prints the correct list out. But my function doesn't return anything at all. What am I doing wrong?
You should define listSecond in your function and return it from there.
This way if you run it multiple times, you only return your input list and not all the previous ones combined.
def iterateandremove (listInitial, num):
listSecond = []
for i in listInitial:
if i != num:
listSecond.append(i)
return (listSecond)
removed = iterateandremove(listInitial, 11)
print(removed)
#[20, 33, 24, 0, 4, 3]
You could also do this with a simple list comprehension without declaring listSecond
def iterateandremove(initial, num):
return [n for n in initial if n != num]
When I run the code it prints the correct list out. But my function doesn't return anything at all. What am I doing wrong?
That's because you didn't assign it to a variable. You'll also want to create a new container within the function, and not use a global variable. Try this:
def iterate_and_remove(list_initial, num):
list_second = []
for i in list_initial:
if i != num:
list_second.append(i)
return list_second
result = iterate_and_remove([1,2,3,4], 4)
print(result)
You could also do this with a list comprehension:
list_second = [i for i in list_initial if i != 11]
Another alternative;
listInitial = [20, 33, 24, 11, 0, 4, 3, 11]
def iterateandremove(listInitial, num):
return list(filter((num).__ne__, listInitial))
print(iterateandremove(listInitial, 11))
[20, 33, 24, 0, 4, 3]
lambda function also a good candidate for this;
listInitial = [20, 33, 24, 11, 0, 4, 3, 11]
def iterateandremove(listInitial, num):
return list(filter(lambda digit: digit != num, listInitial))
print(iterateandremove(listInitial, 11))
[20, 33, 24, 0, 4, 3]
Everything seems ok and the function is returning the list without 11.
returnedList = iterateandremove (listInitial, 11)
print(returnedList) #[20, 33, 24, 0, 4, 3]
def iterateandremove(listInitial, num):
return [n for n in listInitial if n != num]
listInitial = [20, 33, 24, 11, 0, 4, 3, 11]
print(iterateandremove(listInitial, 11))
If you are using python3, the list comprehension would do the work for you like the code above.
If you are using python2, I would suggest using python3 instead, for more details, see https://www.python.org/doc/sunset-python-2/
I'm trying an exercise that wants me to return a new list that contains all the same elements except the negative numbers which are turned into zeros in the returned list.
I have used a for loop to loop through the parameter list and if the number is below 0, I would append it to a new list but times it by 0. However, I get weird outputs such as empty lists. For example, the code below should print:
[0, 0, 9, 0, 0, 34, 1]
[9, 34, 1]
[0, 0, 0]
Please stick to using list methods thanks.
The code:
def get_new_list_no_negs(num_list):
new_list = []
for i in range(len(num_list)):
if i < 0:
new_list.append(num_list[i] * 0)
return new_list
def main():
print("1.", get_new_list_no_negs([-3, -6, 9, 0, 0, 34, 1]))
print("2.", get_new_list_no_negs([9, 34, 1]))
print("3.", get_new_list_no_negs([-9, -34, -1]))
main()
This should do:
def get_new_list_no_negs(num_list):
return [max(num, 0) for num in num_list]
the max function is a python builtin that will return the largest between the passed numbers.
Try this
l = [-2, -1, 0, 1, 2]
# this
l = [i for i in l if i > 0 else 0]
# or
l = [max(i, 0) for i in l]
The enumerate() function adds a counter to an iterable.
So for each element in a cursor, a tuple is produced with (counter, element); the for loop binds that to row_number and row, respectively.
l = [-2, -1, 0, 1, 2]
for index, value in enumerate(l):
if value < 0:
l[index] = 0
print(l)
O/P:
[0, 0, 0, 1, 2]
Forgive me if I do not understand the topic well.
I am implementing a basic(found it on youtube) bubble sort algorithm. As opposed to the example "list = [3, 4, 5, 9, 0, 2, 1]" I decided to try and implement different numbers and got an organized but not "sorted" list, from the perspective I learned. I am not unhappy with the output I am just curious what others have to say about my varying results and possibly get some insight on this.
This is using python on Visual-studio with a windows computer.
The original code is:
def bubblesort(list):
print("bubblesort")
for k in range(0,len(list)-1, 1):
for i in range(0,len(list)-1,1):
if list [i] > list[i + 1]:
temp = list[i]
list[i] = list[i + 1]
list[i + 1] = temp
list = [43, 7, 30, 234, 35, 77, 79, 45, 34, 21, 26]
print(list)
bubblesort(list)
print(list)
outputs:
[43, 7, 30, 234, 35, 77, 79, 45, 34, 21, 26]
bubblesort
[7, 21, 26, 30, 34, 35, 43, 45, 77, 79, 234]
This is how I altered to explore results:
def bubblesort():
for i in range(0, len(list)-1, 1):
if list[i] > list[i + 1]:
list[i] = list[i + 1]
list = [10,110,13,00,0,110]
list = [10,00,11,00,0,1111]
list = [10,101,00,10,0,110]
print(list)
print(list)
print(list)
sorry about the randomness of my numbers, I messed with a few to see if it would sort the same(and it did, exactly the same). It lined certain numbers up in columns, which is cool, but I expected them to be sorted in order of value like above or even include different numbers I added after.
So basically I expected something along the lines of this:
[0,00,10,13,110,110]
[0,00,00,10,11,1111]
[0,00,10,10,101,110]
The actual output is:
[10, 101, 0, 10, 0, 110]
[10, 101, 0, 10, 0, 110]
[10, 101, 0, 10, 0, 110]
By doing
list = [10,110,13,00,0,110]
list = [10,00,11,00,0,1111]
list = [10,101,00,10,0,110]
you assign new content to list in each line, so this code is in fact equivalent to
list = [10,101,00,10,0,110]
I would alter code into following form:
def bubblesort(lst):
for i in range(len(lst)-1):
if lst[i] > lst[i + 1]:
lst[i] = lst[i + 1]
lst1 = [10,110,13,00,0,110]
lst2 = [10,00,11,00,0,1111]
lst3 = [10,101,00,10,0,110]
bubblesort(lst1)
bubblesort(lst2)
bubblesort(lst3)
print(lst1) #output: [10, 13, 0, 0, 0, 110]
print(lst2) #output: [0, 0, 0, 0, 0, 1111]
print(lst3) #output: [10, 0, 0, 0, 0, 110]
Note that I added lst argument for bubblesort so it could be used not only on one variable with fixed name. Please avoid using list as variable name in Python language, as there exist already built-in list function.
Note that that bubblesort function is not proper implementation of sorting, although as I am confused what do you want exactly to do, I left it as is.
I have a very large data set of of consecutive values, containing gaps of varying size and frequency.
The difference between each number in the series stays the same but after a gap break the series doesn't necessarily begin at a point in the original series.
A very simplistic example of this is: 1, 3, 5, 7, 14, 16, 18, 20 (and also what I've been using to test with).
Sample of the data I'm actually using: 1996.40197023,
1996.40199193,
1996.40201362,
1996.40203531,
1996.40240752,
1996.40242921,
1996.40245091,
1996.40247257,
1996.40249426,
1996.40251592.
This is the way that I have tried so far to accomplish this:
date = [1, 3, 5, 7, 9, 14, 16, 18, 20]
ndate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
diff = 2
for i in range(9):
for j in range(15):
if date[i+1]-date[i] > diff:
ndate[j+1] == date[i+1] + diff
elif ndate[j+1] - date[i+1] > diff:
ndate[j]+diff == ndate[j+1]
else:
ndate[j] == date[i+1]
print ndate
but I keep getting "list index out of range" type errors.
Is this the right way of going about this or is there a better way (considering I have in excess of 84,000 data points to work through)?
Thanks
Assuming you want to generate output such that gap values stay more-or-less consistent, I'd go with a generator-based approach here.
Yield elements one at a time from your original series, and if the gap to the next element is greater than your expected delta, generate fill values on the fly until you catch up to it:
def smooth(series, delta=2, tol=0.001):
it = iter(series)
last = next(it)
yield last
for i in it:
while abs(i - (last + delta)) > tol:
last += delta
yield last
last = i
yield last
And examples:
list(smooth([1, 3, 5, 7, 9, 14, 16, 18, 20]))
# [1, 3, 5, 7, 9, 11, 13, 14, 16, 18, 20]
s = [1996.40197023, 1996.40199193, 1996.40201362, 1996.40203531,
1996.40240752, 1996.40242921, 1996.40245091, 1996.40247257,
1996.40249426, 1996.40251592]
list(smooth(s, delta=s[1]-s[0], tol=1e-7))
# [1996.40197023, 1996.40199193, 1996.40201362, 1996.40203531, 1996.40205701, 1996.4020787099998, 1996.4021004099998, 1996.4021221099997, 1996.4021438099996, 1996.4021655099996, 1996.4021872099995, 1996.4022089099994, 1996.4022306099994, 1996.4022523099993, 1996.4022740099992, 1996.4022957099992, 1996.4023174099991, 1996.402339109999, 1996.402360809999, 1996.402382509999, 1996.4024042099988, 1996.40240752, 1996.40242921, 1996.40245091, 1996.40247257, 1996.40249426, 1996.40251592]
This will need manual specification of your delta and tolerance, but you could probably write functions to sniff those out.
I wanted to know if is safe ( documented behaviour? ) to delete the domain space of an iterator in execution in Python.
Consider the code:
import os
import sys
sampleSpace = [ x*x for x in range( 7 ) ]
print sampleSpace
for dx in sampleSpace:
print str( dx )
if dx == 1:
del sampleSpace[ 1 ]
del sampleSpace[ 3 ]
elif dx == 25:
del sampleSpace[ -1 ]
print sampleSpace
'sampleSpace' is what I call 'the domain space of an iterator' ( if there is a more appropriate word/phrase, lemme know ).
What I am doing is deleting values from it while the iterator 'dx' is running through it.
Here is what I expect from the code :
Iteration versus element being pointed to (*):
0: [*0, 1, 4, 9, 16, 25, 36]
1: [0, *1, 4, 9, 16, 25, 36] ( delete 2nd and 5th element after this iteration )
2: [0, 4, *9, 25, 36]
3: [0, 4, 9, *25, 36] ( delete -1th element after this iteration )
4: [0, 4, 9, 25*] ( as the iterator points to nothing/end of list, the loop terminates )
.. and here is what I get:
[0, 1, 4, 9, 16, 25, 36]
0
1
9
25
[0, 4, 9, 25]
As you can see - what I expect is what I get - which is contrary to the behaviour I have had from other languages in such a scenario.
Hence - I wanted to ask you if there is some rule like "the iterator becomes invalid if you mutate its space during iteration" in Python?
Is it safe ( documented behaviour? ) in Python to do stuff like this?
From the Python tutorial:
It is not safe to modify the sequence
being iterated over in the loop (this
can only happen for mutable sequence
types, such as lists). If you need to
modify the list you are iterating over
(for example, to duplicate selected
items) you must iterate over a copy.
The slice notation makes this
particularly convenient:
>>> for x in a[:]: # make a slice copy of the entire list
... if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']
Generally speaking no, it's not safe and you may get unpredictable behaviour. Iterators aren't required to behave in an specific way under these circumstances.
What's happening in your example is
# list is [0, 1, 4, 9, 16, 25, 36]
if dx == 1:
# we're at index 1 when this is true
del sampleSpace[ 1 ]
# we've removed the item at index 1, and the iterator will move to the next valid position - still index 1, but in a mutated list. We got lucky in this case
# the list now contains [0, 4, 9, 16, 25, 36]
del sampleSpace[ 3 ]
# we remove the item at index 3 which is (now) value 16
# the list now contains [0, 4, 9, 25, 36]
elif dx == 25:
del sampleSpace[ -1 ]
# we remove the final item, list now looks like
# the list now contains [0, 4, 9, 25]
What do you mean by safe? Your code happens not to raise any errors, but it is a distinct possibility of course, consider this:
>>> a = range(3)
>>> for i in a:
del a
Traceback (most recent call last):
File "<pyshell#13>", line 2, in <module>
del a
NameError: name 'a' is not defined
>>> a
[0, 1, 2]
>>> for i in a:
del a[i+1]
Traceback (most recent call last):
File "<pyshell#27>", line 2, in <module>
del a[i+1]
IndexError: list assignment index out of range
It is not clear why would you want to do this, but there is no additional rules applicable to iterators. They're acting exactly as any other type would.