Working in Python, how would I write code to remove negatives from an unknown list of integers using for loops and if statements?
def mod_lis (list):
for i in range(len(list)):
if list[i] < 0:
del list[i]
return list
The problem with your code is that you modify your list during your for loop. The result is that you jump over elements this way and get an IndexError soon since your list has been shortened.
You can do this with this list comprehension:
mylist = [val for val in mylist if val>=0]
You can use filter() and a lambda function:
my_list = filter(lambda x : x >= 0, mylist)
It's better to make a copy of the list without selected items, but if you have to modify in place, try this:
def remove_negatives(list):
pos = 0
for item in list:
if item >= 0:
list[pos] = item
pos += 1
del list[pos:]
Related
I am doing a conditional list comprehension e.g. newlist = [x for x in list if x % 2 == 0]. I want to limit the length of the resulting list to a specific number.
Is this possible without first comprehending the entire list and then slicing it?
I imagine something that has the functionality of:
limit = 10
newlist = []
for x in list:
if len(newlist) > limit:
break
if x % 2 == 0:
newlist.append(x)
Slicing the original list (e.g. [x for x in list[:25] if x % 2 == 0] is not possible, as the if condition does not return True in any predictable intervals in my specific use case.
Many thanks in advance.
Please don't name any variables list as it shadows the built-in list constructor. I used li as a replacement for the input list here.
import itertools as it
gen = (x for x in li if x % 2 == 0) # Lazy generator.
result = list(it.islice(gen, 25))
Since you are creating a list with the list comprehension you can slice your list directly after it is created.
[x for x in list[:25] if x % 2 == 0][:limit]
I have a list of numbers and I want to check if a definite sequence exists in that list. For example, for [1,1,2,2,3,3,3,4,5,5,6] how can I determine if the sequence 3-4-5 exists?
I tried using nested loops, but ran into a problem with break/continue. I am now reducing the list to its unique elements and seeing if my sequence exists:
ls = [1,1,2,2,3,3,3,4,5,5,6]
uniq_ls = []
for item in ls:
if item not in uniql:
uniq_ls.append(item)
for ii, item in enumerate(uniq_ls):
if item == 3:
if uniq_ls[ii+1] == 4:
if uniq_ls[ii+2] == 5:
print('yes, sequence exists')
Above method works, but I want to do this without reducing the original list to its unique elements.
How can I do this?
As pointed out by some folks, this method will work only if the original list is sorted.
It will not work for a list like [1,1,1,3,2,2,4,3,3,4,4,4,4,5,3,2,1]
I need it to work for a unsorted list like this one.
You can use this function:
def f(lst, seq):
for n in range(len(lst)-len(seq)+1):
if lst[n:n+len(seq)] == seq:
return True
return False
print(f([1,1,2,2,3,3,3,4,5,5,6], [3,4,5]))
Output:
True
You can also turn that into a one-liner:
def f(lst, seq):
return any(lst[n:n+len(seq)] == seq for n in range(len(lst)-len(seq)+1))
I worked out a solution to this when the list is unsorted. I am not sure if this is the most elegant, pythonic way -
List L1 is [1,1,1,3,2,2,4,3,3,4,4,4,4,5,3,2,1]
I will have an empty list L2 = [] and add first item of list to it.
Then I will append L2 with item from L1 if previous item is not the same as current item
So L2 eventually should look like [1,3,2,4,3,4,5,3,2,1]
From this list it will be easy to find a sequence 3-4-5.
New code:
l1 = [1,3,2,4,3,4,5,3,2,1]
l_uni = []
for ii, item in enumerate(l1):
if ii==0:
l_uni.append(item)
elif l1[ii] != l1[ii-1]:
l_uni.append(item)
for jj in range(0,len(l_uni)):
try:
if l_uni[jj] == 3:
if l_uni[jj+1] == 4:
if l_uni[jj+2] == 5:
print('found sequence')
break
except IndexError:
print('no sequence')
def back_interleave(first, second):
if first == [] and second == []:
return []
elif first == []:
return second[::-1]
elif second == []:
return first[::-1]
else:
newlist = []
for i in range(len(first)-1, 0,-1):
newlist.append(first[i])
newlist.append(second[i])
for j in range(len(second)-len(first)-1,0,-1):
newlist.append(second[i])
return newlist
can anybody tells me what's wrong with my code towards this question.
I'm not exactly sure what's wrong with your code, but the second and third if-statements appear to use built-in list reversing functionality which the original problem forbids.
What I would do is determine the length of the longer list, then iterate through both lists backwards.
def back_interleave(first, second):
newlist = []
# You want to iterate through the length of the longer list
length = max(len(first), len(second))
for x in range(length):
# start appending elements from the back of the list
index = -1*(x+1)
if x < len(first):
newlist.append(first[index])
if x < len(second):
newlist.append(second[index])
return newlist
The problem in your code is when you use the range function, the stop value is exclusive i.e., the index 0 is becoming exclusive in your case. And also in the j loop the values at index i are being stored instead of the values at index j.
#CyanideTesla has given the code that works pretty well for your problem
Given that l = [[1,2,3], [3,4,5],[5,6]], is there a method to return a list that consists of all positions of 3 within l; i.e. return [2,3]. A sample code I wrote is:
def pos_in_lists(seq, elem):
while i < len(seq):
elem_pos = seq[i].index(elem)
return [elem_pos]
When I run this, it only returns 2, which is not the result I want. What is my mistake? Also, is there a more simple way to solve my problem?
Your code only returns a list with one element (return [elem_pos]). You need to have a list variable (result) outside the loop to keep track of the result of previous lists by appending to that list.
def pos_in_lists(seq, elem):
result = []
i = 0
while i < len(seq):
if elem in seq[i]:
elem_pos = seq[i].index(elem)
result.append(elem_pos)
i += 1
return result
Another simpler alternative is to use list comprehension
def pos_in_lists(seq, elem):
return [l.index(elem) for l in seq if elem in l]
You need to increment "i" each loop
"return" forces the loop to exit. That should be outside the loop at the end of the code.
According to my understanding of the problem, Given list l = [[1,2,3], [3,4,5],[5,6]] and if we have to find 3, the output list should be [2,0].
Following mistakes are there in the code provided:
The code is not working as i is not defined in your method before using it.
We need to store positions of all 3 value present in the list, thus we need to have a list in which we store all the positions of 3 that we can find in the list. You have returned the result as soon as you have found one value. Thus, you are getting only 2.
seq[i].index(elem) will throw value error if 3 is not in the list.
Solution
def pos_in_lists(seq, elem):
res = []
for innerList in seq:
if elem in innerList:
res.append(innerList.index(elem))
return res
pos_in_lists(l,3)
Result would be [2,0]
we can use list comprehension as well:
def pos_in_lists(seq, elem):
return [innerList.index(elem) for innerList in seq if elem in innerList]
I'm stuck on this question for checking odd numbers, with for loop method
I've been given part of this code to produce odd numbers only
def get_odds(items):
new_list = []
return new_list
If anyone can help, that would be great - thanks!
You can use a list comprehension:
def get_odds(items):
new_list = [item for item in items if item % 2 == 1]
return new_list
Edit: If you have to use a for loop, you can write something in the lines of:
def get_odds(items):
new_list = []
for item in items:
if item % 2 == 1:
new_list.append(item)
return new_list
As you will see, this is just a longer way of writing the first solution.
How about
for a in range(10000):
if a%2==1:
new_list.append(a)
I am sure there are better algorithms but it is early and I have not had an coffee yet :)
def get_odds(items):
new_list = [] ###create an empty container to store odd no.s when passed into it
for item in items: ### loop over your items (a list probably)
if item%2 != 0: ####here u will get odd numbers(Yes ==1 also works)
new_list.append(item)
return new_list
Note: though List comprehension are more pythonic way, but a for loop is easy to understand logic.
l = lambda(y) : [i for i in xrange(y) if i%2!=0]
print l(1000)
Or simply
odd_list = [i for i in xrange(1000) if i%2!=0]