remove even numbers from a list - python

How can I remove even numbers from a list?
a = []
i = 0
while i < 10:
c = int(raw_input('Enter an integer: '))
a.append(c)
i += 1 # this is the same as i = i + 1
for i in a:
if i % 2 == 0:
a.remove(i)
print(a)
This keeps asking for numbers even after 10 have been entered

Why not preventing the append if the number is even, instead of adding and then checking for removal?
a = []
counter = 0
while counter < 10:
c = int(raw_input('Enter an integer: '))
if c % 2 != 0:
a.append(c)
counter += 1
print(a)

i is reassigned by the for statement. Use a different variable.

If you want to see how to 'filter' a list according to a predicate, here is an example:
a_without_even = filter(lambda x: x%2==1, a)

def removalDiffMethod(self, array):
l=0
r=len(array)
while l<r:
if array[l]%2==0:
array[l:r] = array[l+1:r+1]
r-=1
else:
l+=1
return array[:r]

Something like this?
your_dirty_list = [2,3,3,3,4,4,2,2,7,7,8]
your_clean_list = [clean_dude for clean_dude in your_dirty_list if clean_dude % 2]
Out[]: [3, 3, 3, 7, 7]

Related

What is wrong in the code, I want output as [10,20,30,40,50,60,70,80,90,100]

My code is as follow:
factors = []
num = 1
while num <= 100:
num+=1
if num % 10:
break
factors.append(num)
print(factors)
It is giving me the output: [2, 3, 4, 5, 6, 7, 8, 9]
That's because you're breaking out of the loop instead of just adding to the 'factors' list if num % 10 is 0. Remove 'break' and you should be good.
Without nitpicking further on the code (which is extremely inefficient), here's how you can quickly fix it.
while num <= 100:
num+=1
if num % 10 == 0:
factors.append(num)
x = list((i for i in range(1,101))) # generate a list, 1 to 100
result = filter(lambda x1: x1%10==0,x)
the lambda expression means, if x1%10 == 0, return true.
filter function will use the lambda to find all items in list x that %10 equals 0.
this is what you want to do:
factors, num = [], 1
while num <= 100:
num += 1
if num % 10 == 0:
factors.append(num)
print(factors)

The sum of numbers

I've been making a program that finds two numbers in a random list and prints them if their sum is 8.
Honestly, I've been sitting here for half an hour and idk what's going on. I think I'm pretty close, but in rare cases it doesn't find an exitsting combination(list = [1,4,4,9] -> No combination). Also in rare cases I will get an error saying
RecursionError: maximum recursion depth exceeded in comparison
Here's my code:
import random
list = []
for i in range(1,5,1):
newNum = random.randint(1,10)
list.append(newNum)
list.sort()
sum = 8
print('\nRandomly generated list:')
print(list)
firstNum = list[0]
lastNum = list[-1]
newList = []
def isSum(a,b):
if a + b == sum:
if list.index(a) == list.index(b):
print('\nThere isnt a combination.')
else:
newList.append(a)
newList.append(b)
print('\nCombination:')
print(newList)
elif a + b < sum:
temp = list.index(a)
temp += 1
if temp > list.index(lastNum):
print('\nThere isnt a combination.')
else:
a = list[temp]
isSum(a,b)
else:
temp = list.index(b)
temp -= 1
if temp < list.index(firstNum):
print('\nThere isnt a combination.')
else:
b = list[temp]
isSum(a,b)
isSum(firstNum,lastNum)
I'm just a beginner, don't get angry if I made a stupid mistake :3
You can use itertools module for generating all combinations of your list, then filter that by calculating the sum of each combination, for example this:
import itertools
a = [1, 4, 4, 9] # any list of nums
groups = 2
result = 8
combinations = [combination for combination in itertools.combinations(a, groups)]
output = [combination for combination in combinations if sum(combination) == result]
print(output)
>>> [(4, 4)]
Recursion really isn't ideal in Python, and your code could certainly be simplified.
This should return all the pairs.
import itertools as itt
import random
from typing import List, Tuple
def is_comb_sum(nums: List[int], comb_size: int, target_sum: int) -> List[Tuple[int, ...]]:
combs = []
for curr_pair in itt.combinations(nums, comb_size):
curr_sum = sum(curr_pair)
if curr_sum == target_sum:
combs.append(curr_pair)
return combs
nums_list = [random.randint(0, 10) for _ in range(5)]
print(nums_list)
res = is_comb_sum(nums_list, 2, 8)
print(res)
If you only want to print each combination once, you can use a set to identify the distinct numbers that are present. Then, for each of these number, you determine which complementing value is need to reach your target (8) and if it is also in the set then the pair exists. The only exception to this is when the number is exactly half of the target (i.e. 4) in which case you have to make sure there are at least two instances of that number in the list:
target = 8
count = 4
numbers = [random.randint(1,10) for _ in range(count)]
print(numbers)
numberSet = set(numbers)
for number in numberSet:
other = target-number
if other not in numberSet: continue
if other > number: continue # avoid duplicates such as 2+6=8 and 6+2=8
if other == number and numbers.count(number) < 2: continue
print(number,"+",other,"=",target)
Output:
[7, 2, 6, 1]
6 + 2 = 8
7 + 1 = 8
If you want to print all the combinations, you can use the Counter object from the collection modules and either print the number of occurrences or repeat the printed lines:
target = 12
count = 8
numbers = [random.randint(1,10) for _ in range(count)]
print(numbers)
from collections import Counter
numberCounts = Counter(numbers)
for number in numberCounts:
other = target-number
if other > number: continue
pairCount = numberCounts[number] * numberCounts[other]
if number == other:
pairCount = (pairCount - numberCounts[number]) // 2
if pairCount > 0:
print(number,"+",other,"=",target,"occurred",pairCount,"time(s)")
Output (target of 12 in list of 8):
[7, 6, 5, 5, 6, 6, 3, 4]
7 + 5 = 12 occurred 2 time(s)
6 + 6 = 12 occurred 3 time(s)

Double the digits in string and apply them

eg : `a = "452398" i want to take all the indices(one after - one after digits) like (4 , 2 , 9) double them == (8 , 4 , 18)
next step to check if the doubled digits is greater than 9 if so need to subtract from 9 (8 , 4 , 9) and finally i want add the digits in a ("854398") it must a string any idea how to do it ?
i tired for loop using range , len skip i sorted out everything till the last step but i couldn't apply the digits in "a" . so deleted the whole loop :(
This does what you described, but why would you want to do that:
a = "452398"
a_list = [int(x) for x in a]
numbers = [x*2 for x in a_list[::2]]
numbers = [x-9 if x>9 else x for x in numbers]
result = [j for i in zip(numbers,a_list[1::2]) for j in i]
result = map(str, result)
result = ''.join(result)
string is immutable so first you should create a list of characters using your string
a = '452398'
new = list(a)
then create a loop to do your conditions and change the value of characters in the list
for i in range(0,len(new),2):
num = int(new[i]) * 2
if num > 9:
new[i] = num - 9
else:
new[i] = num
now overwrite the value of your variable a using your new list of characters.
a = ''.join(map(str,new))
Here is the whole code.
a = '452398'
new = list(a)
for i in range(0,len(new),2):
num = int(new[i]) * 2
if num > 9:
new[i] = num - 9
else:
new[i] = num
a = ''.join(map(str,new))
print(a)
Here's how you do it using list comprehensions
A = "452398"
res = "".join([(str(min(int(a) * 2, 9)) if idx % 2 == 0 else a) for idx, a in enumerate(A)])
One of the simple answers could be.
a = '452398'
b = []
for i, x in enumerate(a):
if (i%2 == 0):
res = int(x) * 2
if len(str(res)) > 1:
res = res - 9
b.append(res)
else:
b.append(x)
b = map(str, b)
b = ''.join(b)
print(b)

How do I get smallest postitive integer not present in the array

I am trying to find out smallest positive number not present in the list a
def smallitem(a):
a = sorted(set(a))
lst = []
for item in a:
item + = 1
if item not in a:
lst.append(item)
continue
mst = []
for item in lst:
if item < 1:
item += 1
if item not in a:
mst.append(item)
continue
n = 0
if mst:
n = min(mst)
return n or min(lst)
I think I have got the solution but it doesnt look correct to me the way I have done it.
for example:
smallitem([-1, -3]) # 1
smallitem([1,3,6,4,1,2, 87]) # 5
You can convert the list to a set and then keep incrementing a positive integer from 1 until it is not found in the set:
def smallitem(a):
set_a = set(a)
i = 1
while i in set_a:
i += 1
return i
Perhaps there's a lighter way do this.
The time complexity is always O(n).
def small_item(a):
s = set(a)
for i in range(1, max(s)):
if i not in s:
return i
return max(max(s) + 1, 1)
print small_item([1,3,6,4,1,2, 87])
print small_item([-1, -3])
Here's anther way to do this:
def smallitem(l):
l = list(set(sorted(l)))
x = l[0]
for i in l:
if i != x and x >= 1:return x
x += 1
return 1
Testing:
>>> smallitem([-3, -1])
1
>>> smallitem([1, 3, 6, 4, 1, 2, 87])
5
>>>

Print the length of the longest continuous sequence of alternating odd and even numbers

How would I go about reading integers until -1 is input and then printing the length of the longest continuous sequence of numbers where there are
alternating odd then even numbers?
I've achieved the first section but it went downhill from there.
Some testing lists:
[1,2,3,4,5,10,6,7,8,20,25,30,40,-1]
[6,7,8,20,25,30,40,1,2,3,4,5,10,15,20,-1]
Here is my code:
evenOdd=[]
while True:
try:
n=int(input())
if n != -1:
evenOdd.append(n)
except:
break
evenOdd=[]
longest = 0
length = 0
for i in range(len(evenOdd)):
if ((evenOdd[i-2]% 2 == 0) and (evenOdd[i-1]% 2 == 1) and (evenOdd[i]% 2 == 0):
length += 1
else:
longest = max(longest, length)
length = 0
print(longest)
One option would be to keep track of the longest sequence as you go:
longest = []
current = []
while True:
n = int(input("Enter value: "))
if n == -1:
break
if current and current[-1] % 2 != n % 2:
current.append(n)
else:
current = [n]
if len(current) > len(longest):
longest = current
The upside here is there's no post-processing to be done when the -1 is entered, the result is ready to go.
You can use itertools.cycle to alternate between a remainder of 0 and 1, and use itertools.groupby to group odd-even sequences:
from itertools import groupby, cycle
l = [1,2,3,4,5,10,6,7,8,20,25,30,40]
r = cycle((0, 1))
print(max(sum(1 for i in g) for _, g in groupby(l, key=lambda n: n % 2 == next(r))))
This outputs: 6 (since the longest odd-even sequence is 1,2,3,4,5,10)
This is how I did. I think this might be simpler than the above examples.
def alternating(lst):
longSeries = []
currentSeries=[]
for i in range (len(lst)-1):
if i == 0:
currentSeries = [lst[0]]
if(abs(lst[i] - lst[i+1]) % 2 == 1):
currentSeries.append(lst[i+1])
else:
currentSeries = [lst[i+1]]
if(len(currentSeries) > len(longSeries)):
longSeries = currentSeries
print ("The longest series is: " +str(longSeries))
print(len(longSeries))
You can apply itertools.groupby twice:
import itertools
d = [[1,2,3,4,5,10,6,7,8,20,25,30,40,-1], [6,7,8,20,25,30,40,1,2,3,4,5,10,15,20,-1]]
def key_func(d):
start= not d[0]%2
for i in d[1:]:
if i%2 == start:
start = (not i%2)
else:
return False
return True
for l in d:
new_l = [list(b) for _, b in itertools.groupby(l, key=lambda x:x%2)]
second_l = [[i for [i] in b] for a, b in itertools.groupby(new_l, key=lambda x:len(x) ==1) if a]
print(max(second_l, key=lambda x:[key_func(x), len(x)]))
Output:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 10, 15, 20, -1]

Categories

Resources