Appending a list through if condition in python - python

This could be a very basic question, but I realized I am not understanding something.
When appending new things in for loop, how can I raise conditions and still append the item?
For instance:
alist = [0,1,2,3,4,5]
new = []
for n in alist:
if n == 5:
continue
else:
new.append(n+1)
print(new)
Gets me
[1, 2, 3, 4, 5]
How do I get
[1, 2, 3, 4, 5, 5] # 4 is incremented, 5 is added 'as is'
Essentially, I want to tell python to not go through n+1 when n==5.
Would this be the only solution? append n==5 separately in a list and then sum new and the separate list?

Why don't you just append the 5 instead of using continue, is there any other condition?
for n in alist:
if n == 5:
new.append(n)
else:
new.append(n+1)

You can use the fact the a boolean True is 1 while a False is 0 combined with a list comprehension like:
Code:
[x + int(i != 5) for i, x in enumerate(alist)]
Test Code:
alist = [0, 1, 2, 3, 4, 5]
new = [x + int(i != 5) for i, x in enumerate(alist)]
print(new)
Result:
[1, 2, 3, 4, 5, 5]

Seems like you didn't get the point of 'continue'. The Python keyword 'continue', means you do nothing in that if condition, so basically you tell the program "do nothing" when n == 5 and if n is not 5, you do some operation. That's why you got your original result. Hope it may help.

Related

find the first unique element in the integer list : python

def findFirstUnique(lst):
# Write your code here
for x in lst:
print ('x is:{} '.format(x))
lst.remove(x)
print lst
if x not in lst:
return x
print ('final output is : {}'.format(findFirstUnique(lst)))
Apparently it seems to go through for certain cases like this: [9, 2, 3, 2, 6, 6, 9]
And for some other cases, the for loop seems to behave so weirdly: [4, 5, 1, 2, 0, 4]
and the output for the second case :
x is:4 [5, 1, 2, 0, 4]
x is:1 >>> Why is it not picking "5" as the next value?? [5, 2, 0, 4] final output is : 1
I am kinda losing it now that I am not able to understand this for loop!
Any help would be appreciated.
It is a different approach but it will return the first unique in the list
def findFirstUnique(lst):
for x in lst:
if lst.count(x) == 1:
return x
return None
This should suffice, it is succinct and fast.
[*filter(lambda x: lst.count(x) == 1, lst)][0]
Data:
lst = [9, 2, 3, 1, 2, 6, 6, 9]
In terms of speed, any solution which requires looping over the list for each element in order to check the number of counts (whether as an explicit loop or by using lst.count()) is going to scale as O(n^2) in the worst case. If you start by making a dictionary of counts, and then use the dictionary lookup for each item to check its count, then this should be not much worse than O(n). The code to obtain the counts in pure Python is not particularly difficult, but in fact collections.Counter in the standard library will do it for us, so we may as well use that:
from collections import Counter
def findFirstUnique(lst):
counts = Counter(lst)
for x in lst:
if counts[x] == 1:
return x
else:
return None
if __name__ == '__main__':
lst = [9,2,3,2,6,6,9]
print(findFirstUnique(lst))
The for loop actually iterates the list using the element's index (say i). At the 2nd loop, i=1, lst=[5, 1, 2, 0, 4]. So, the current element is 1, not 5. As a rule, you should not remove or insert any element while iterating.
def findFirstUnique(lst):
for i, x in enumerate(lst):
print('x is:{} '.format(x))
print(lst[:i]+lst[i+1:])
if x not in lst[:i]+lst[i+1:]:
return x
print(findFirstUnique([4, 5, 1, 2, 0, 4]))

List index out of range using While loop

This is my first time posting and I am a bit of newbie so please excuse any errors in my question. I have to create a function that uses the While loop and takes in a list of numbers and adds each number to a new list until the a specific number is reached. For example - I want each number in a list to be added until the number 5 is reached in the list. If the number 5 is not in the list, then I would get the entire list as is. The issue I am having is with this last part. My current code, posted below, can give me a new list of numbers that stops at the number 5 but I get the "List index out of range" error when the number 5 is not included in the list. I am sure its something small that I am not factoring in. Any help or guidance on what I am doing wrong would be greatly appreciated.
def sublist(x):
i = 0
num_list = []
while x[i] != 5:
num_list.append(x[i])
i = i + 1
return num_list
print(sublist([1, 2, 5, 7])) #works fine
print(sublist([1, 2, 7, 9])) #list index out of range error
As others have pointed out, it is best to use a for loop when you already know the number loops you need (e.g.: len(x) in your case).
If you still really want to use a while loop instead, you will need to check every loop to see if you have checked every item in the old list, and exit the loop if you do. Here's what your code could look like if you're using a while loop:
def sublist(x):
i = 0
num_list = []
original_length = len(x)
while i < original_length and x[i] != 5:
num_list.append(x[i])
i = i + 1
return num_list
print(sublist([1, 2, 5, 7])) #works fine
print(sublist([1, 2, 7, 9])) #now also works fine
EDIT: I originally had the check for i < original_length inside the loop, I've changed it to be inside the while condition. BUT BE CAREFUL because the check MUST come before x[i] != 5. What I mean is that using this will work:
while i < original_length and x[i] != 5:
But this will not:
while x[i] != 5 and i < original_length:
This should do the trick. If n (5 in your example) is in the list x it will take the list until that point. Else, it will take the whole list. This isn't the most pythonic option, though, probably someone knows a better way.
def sublist(x, n):
num_list=[]
if n in x:
for i in x:
while i!=n:
num_list.append(i)
else:
num_list=x
return num_list
Your loop will not stop if there is no 5 in the list, so the index i will be equal to the length of x (length of x is out of range) in the iteration when the error happens.
When looping with python, it's better to use for in loops:
def sublist(x):
num_list = []
for n in x:
if n != 5:
num_list.append(n)
else:
break
return num_list
print(sublist([1, 2, 5, 7])) # [1, 2]
print(sublist([1, 2, 7, 9])) # [1, 2, 7, 9]
Try this
def sublist(x):
x.sort()
limit_num = 5
if limit_num not in x:return x
return x[:x.index(limit_num)]
print(sublist([1, 2, 5, 7]))
print(sublist([1, 2, 7, 9]))
Result:[1, 2]
[1, 2, 7, 9]

Checking if you can divide list into 2 with exact sum of numbers that are in them

My problem is that I have a list, for example
l =[1, 2, 3, 4, 5, 15]
and I would like to divide it in two lists, list1 that would have a single element of the actual list which should be the sum of all other numbers in the list, and list2 containing rest. So the output for this would be ([1, 2, 3, 4, 5], [15]) if its possible if not, return False.
This is one way, though not necessarily optimal. It uses the, in my opinion underused, for...else... construct.
I've also reversed the range iterator. This is more efficient in the case you provided.
l = [1, 2, 3, 4, 5, 15]
def splitter(l):
for i in reversed(range(len(l))):
if sum(l[:i]) == sum(l[i:]):
return [l[:i], l[i:]]
else:
return False
splitter(l) # [[1, 2, 3, 4, 5], [15]]
Should it be possible for the positions of the values to change in the list? If not you can try an iteration such as:
l = [1, 2, 3, 4, 5, 15]
dividable = "False"
x = 0
while dividable == "False":
l1 = l[0:x]
l2 = l[x:len(l)]
if sum(l1) == sum(l2):
dividable = "True"
elif x == len(l):
#not possible
break
else:
x += 1
This answer should help in all cases.
No imports required and no sorting required for the data.
def split_list(l):
dividable=False
index=0
for i in range(len(l)):
if l[i]==sum(l)-l[i]:
dividable=True
index=i
break
if dividable:
l1=l[index]
l.remove(l[index])
return (l1,l)
else:
return False
Might not be the optimised way, but a better and clear way to understand for beginners.
split_list([1,2,3,4,5,15])
[15],[1,2,3,4,5]
Hope this helps. Thanks
what about this?
l =[1, 2, 3, 4, 5, 15]
l=sorted(l)
track=[]
for i in l:
track.append(i)
if sum(track) in l and len(track)==len(l[1:]):
print(track,[sum(track)])
output:
[1, 2, 3, 4, 5], [15]
You need to do a couple of steps:
1) Sort the list from small to large. (Into a new list if you don't want to alter the original)
2) Sum every other element of the list and see if it's equal.
3) If false return false
4) if true:
Store the last (biggest) value in a variable and delete this from the duplicate of the original list.
Make a second list with only that last value in it.
Create another new list and add the altered duplicate list and the list made of the biggest element.
Return the last created list.
Then you're done
Brute force:
import itertools
x = [1, 2, 3, 4, 5, 15]
for size in range(1,len(x)):
for sublist in itertools.combinations(x, size):
comp = x[:]
for n in sublist:
comp.remove(n)
if sum(comp) == sum(sublist):
print(comp, sublist)
[1, 2, 3, 4, 5] (15,)
[15] (1, 2, 3, 4, 5)
This approach can handle duplicated numbers.
Using numpy:
def split(l):
c = np.cumsum(l)
idx = np.flatnonzero(np.equal(l, c[-1] / 2.0))
return (l[:idx[0]], l[idx[0]:]) if idx.size > 0 else False
Alternatively, if using Python > 3.2:
import itertools
def split(l):
c = list(itertools.accumulate(l))
h = c[-1] / 2.0
if h in c:
i = l.index(h)
return l[:i], l[i:]
return False
Finally, if you want to use "pure" Python (no imports):
def split(l):
c = [sum(l[:k]) for k in range(1, len(l) + 1)]
h = c[-1] / 2.0
if h in c:
i = l.index(h)
return l[:i], l[i:]
return False

Get previous value based in specific item

I am trying a script where we use a list item and then I will get the previous item.
lst = [1, 3, 4, 6, 8, 10]
next_item = next((x for x in lst if x > 6), None)
print next_item #8
This code works correctly for the item after 6. However i need the item before 6.
I am looking in docs for a prev method but i can't find anything related.
Any idea about that?
Assuming by "before" you mean "previous in lst", it is not necessary to use such a complicated way. This
lst[lst.index(6) - 1]
will give
4
while this
lst[lst.index(6) + 1]
will give
8
Of course you should check for index out of bound errors.
You can loop over the reversed list with a reverse condition :
>>> next((i for i in lst[::-1] if i<6),None)
4
If you are looking for the first number larger than 6 in lst, this is one way to do it:
lst = [1, 3, 4, 6, 8, 10]
lst2 =[]
for num in lst:
if num > 6:
lst2.append(num)
lst2.sort()
print lst2[0]
The output is 8

return a list containing elements of another list

I need to write an expression and I'm completely stuck. I have part of the code that I think I have written correctly but I'm stick on the rest of it. I need the code to return a new list containing every 3rd element in the list, starting at index 0.
For example: if I have the list [0, 1, 2, 3, 4, 5] I need it to return [0, 3]
The code I have so far is:
result = []
i = 0
while i < len(L):
result.append(L[i])
i =
return result
Can someone please help me figure out what I need the i = expression to be for this code to work.
First of all, you can make use of extended slice notation to make things easier:
In [1]: l = [0, 1, 2, 3, 4, 5]
In [2]: l[::3]
Out[2]: [0, 3]
From the docs:
Some sequences also support “extended slicing” with a third “step” parameter: a[i:j:k] selects all items of a with index x where x = i + n*k, n >= 0 and i <= x < j.
As for your code sample, you probably need i = i + 3 or i += 3 there.
Maybe try this:
result = []
for i in range(0, len(L), 3):
result.append(L[i])
return result
Another alternative is to use enumerate.
[j for i, j in enumerate([0, 1, 2, 3, 4, 5]) if i % 3 == 0]
this will give tyou an iterable sequence:
import itertools
l = [0, 1, 2, 3, 4, 5]
itertools.islice(l, 0, None, 3)
to turn it into a list, use the list() function.
impiort itertools
def get_sublist(l):
return list(itertools.islice(l, 0, None, 3))
python 3.2
one way:
>>> [i for i in range(0,len(L),3)]
[0,3]
your method:
result = []
i = 0
while i <= len(L):
result.append(L[i])
i+=3
return result

Categories