Generating a list of EVEN numbers in Python - python

Basically I need help in generating even numbers from a list that I have created in Python:
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, ...]
I have tried a couple different methods, but every time I print, there are odd numbers mixed in with the evens!
I know how to generate even/odd numbers if I were to do a range of 0-100, however, getting only the even numbers from the previous mentioned list has me stumped!
P.S. I've only been using python for a couple days, if this turns out to be extremely simple, thanks in advance!
EDIT: Thanks for all the replies, with your help I've gotten through this little problem.
Here is what I ended up with to complete a little excercise asking to sum the even numbers of fibonacci sequence:
F = [1, 2]
while F[-1] < 4000000
F.append(F[-1] + F[-2])
sum(F[1::3])
4613732

Use a list comprehension (see: Searching a list of objects in Python)
myList = [<your list>]
evensList = [x for x in myList if x % 2 == 0]
This is good because it leaves list intact, and you can work with evensList as a normal list object.
Hope this helps!

The following sample should solve your problem.
Newlist = []
for x in numList:
if x % 2 == 0:
print x
Newlist.append(x)

You can do this with a list comprehension:
evens = [n for n in numbers if n % 2 == 0]
You can also use the filter function.
evens = filter(lambda x: x % 2 == 0,numbers)
If the list is very long it may be desirable to create something to iterate over the list rather than create a copy of half of it using ifilter from itertools:
from itertools import ifilter
evens = ifilter(lambda x: x % 2 == 0,numbers)
Or by using a generator expression:
evens = (n for n in numbers if n % 2 == 0)

In your specific case my_list[1::3] will work. There are always two odd integers between even integers in fibonacci: even, odd, odd, even, odd, odd.....
>>> my_list = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368]
>>>
...
>>> my_list[1::3]
[2, 8, 34, 144, 610, 2584, 10946, 46368]

Just check this
A = [i for i in range(101)]
B = [x for x in A if x%2 == 0]
print B

iterate through the list and use the modulo operator to check even
for number in list:
if (number % 2) == 0:
##EVEN

Just for fun, checking if number%2 != 1 also works ;)
evens=[x for x in evens_and_odds if number%2 != 1 ]
Note that you can do some clever things to separate out evens and odds in one loop:
evens=[]
odds=[]
numbers=[ evens, odds ]
for x in evens_and_odds:
numbers[x%2 == 1].append(x)
print evens
print odds
The above trick works because logical expressions (==, >, etc.) operating on numbers True (1) and/or False (0).

You can use list comprehension to generate a new list that contains only the even members from your original list.
data = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
then:
new_data = [i for i in data if not i%2]
yields
[2, 8, 34, 144]
Or alternatively use a generator expression if you don't need all of the numbers
at once:
new_data = (i for i in data if not i%2)
The values then would be availabe as needed, for instance if you used a for loop:
e.g.,
for val in new_data:
print val
The advantage of the generator expression is that the whole list is not generated and stored in memory at once, but values are generated as you need them which makes less demand on memory. There are other important differences you might want to read up on at some point if you are interested.

Instead of generating all Fibonacci numbers then filtering for evens, why not generate just the even values?
def even_fibs():
a,b = 1,2
while True:
yield b
a,b = a+2*b, 2*a+3*b
generates [2, 8, 34, 144, 610, 2584, 10946 ...]
then your sum code becomes:
total = 0
for f in even_fibs():
if f >= 4000000:
break
else:
total += f
or
from itertools import takewhile
total = sum(takewhile(lambda n: n<4000000, even_fibs()))

a = range(0,1000)
b = []
for c in a:
if c%2==0:
b.append(c)
print b

You could do this using the filter function as follows:
F = [1, 2]
while F[-1] < 4000000:
F.append(F[-1] + F[-2])
print(F)
print('\n')
#create the variable that could store the sorted values from the list you have created.
sorted_number=list(filter(lambda x:x%2==0,F))
print(sorted_number)

You could use a for and if loop using the length function, like this:
for x in range(len(numList)):
if x%2 == 0:
print(x)
NewList.append(x)

Basically you should create a variable and put your list in and then sort your even numbers list by adding it only the even numbers
numbers = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, ...]
even = [e for e in numbers if e%2==0]

Here are some of the different ways to get even numbers:
CASE 1
in this case, you have to provide a range
lst = []
for x in range(100):
if x%2==0:
lst.append(x)
print(lst)
CASE 2
this is a function and you have to pass a parameter to check if it is an even no or not
def even(rangeno):
for x in range(rangeno):
if rangeno%2 == 0:
return rangeno
else:
return 'No an Even No'
even(2)
CASE 3
checking the values in the range of 100 to get even numbers through function with list comprehension
def even(no):
return [x for x in range(no) if x%2==0]
even(100)
CASE 4
This case checks the values in list and prints even numbers through lambda function. and this case is suitable for the above problem
lst = [2,3,5,6,7,345,67,4,6,8,9,43,6,78,45,45]
no = list(filter(lambda x: (x % 2 == 0), lst))
print(no)

Related

Python List Comprehensions

I am learning python3 list comprehensions. I understand how to format a list comprehension: [equation, for loop, if statement for filtering], but I cannot figure out how to condense three lines of code into a single equation for the 'equation' part.
I am taking a number and adding it to itself and then taking the result and adding it to itself and so on to create a sequence of numbers in the list.
I can accomplish this by declaring x = 1 and then looping the following:
y = x + x
x = y
Can anybody help me to turn this into a single-lined equation and if possible, resources that I might study to help me with this in the future?
Your algorithm is equivalent to multiplying by powers of 2:
x = 3
res = [x * 2**i for i in range(10)]
# [3, 6, 12, 24, 48, 96, 192, 384, 768, 1536]
To see why this is the case, note you are multiplying your starting number by 2 in each iteration of your for loop:
x = 3
res = [x]
for _ in range(9):
y = x + x
x = y
res.append(y)
print(res)
# [3, 6, 12, 24, 48, 96, 192, 384, 768, 1536]
As #timgeb mentions, you can't refer to elements of your list comprehension as you go along, as they are not available until the comprehension is complete.

Getting prime numbers from a list

Given a list lst = [121, 4, 37, 441, 7, 16] , I would like to remove from it all numbers that repeat themselves, resulting in a new string that would be lst = [37,7] (the prime numbers of the original string).
So far I'd only managed to put out this code:
def func(lst,x):
y = []
for i in lst:
for x in range (1, i):
if (i % x) == 0 :
y.append(i)
return y
print(func(lst,3))
Instead of getting lst = [37,7], I'm getting this weird looking list:
[121, 121, 4, 4, 37, 441, 441, 441, 441, 441, 441, 441, 441, 7, 16, 16, 16, 16]
Is there any way I can make this work ?
As this feels like a homework question, I won't give working code, but a strategy. You want to ensure that only the numbers of the original list remain, or filter out the numbers that are not prime.
Slightly more formally, "for each number in the list, determine if it's prime, and if so, include it in a new list".
Your code is 90% there, but your kernel (the primality test) is not correct. The key to testing primality is to ensure that each possible integer divisor does not evenly divide the number in question.
For example, if testing 6, the list of possible "0 remainder" integer divisors is
[1, 2, 3, 4, 5, 6]
The first and last numbers (1 and 6) don't mean anything as far as primality (6/1 is 6, and 6/6 is 1). So, your list of possible divisors to test is now
[2, 3, 4, 5]
From here, I think an insight you're missing in your code is that for a number to be prime, all of its possible divisors must not produce an even number (i.e., remainder of 0).
from math import sqrt
def func(n)
list1=[]
list2=[]
for z in (all(i % x for x in range(2,int(sqrt(i)+1))) for i in n):
list1.append(z)
for i,j in enumerate(list1):
if j == True:
list2.append(n[i])
return list2

Determining Practical Numbers

So I am given a fraction and must determine if the denominator is a practical number. Description of a practical number: What is a practical number?
I already have a function that returns all the factors of the number:
def factorFinder(x):
#Pre: Valid Integer for students
#Post: Returns list of factors for that number
#Takes the number of students as argument and returns all factors for that number
lst = []
for i in range(1, x+1):
if x % i == 0:
lst.append(i)
return(lst)
and a function that given a list of factors as arguments returns a list of sums of all its sublists:
import itertools
def sumsOfSublists(lst):
# Pre: a non-empty list
# Post: returns a list of sums of all possible list sublists of length >= 2
# given a list, returns a sorted list containing sums of
# all combinations of sublists of length 2..list_length
sumList = []
for i in range(2, len(lst)+1):
zlist = list(itertools.combinations(lst,i))
for el in zlist:
sumList.append(sum(el))
return sorted(sumList)
I don't know how to go about testing if the number is practical or not. I don't really understand the concept of a "practical number" even after reading about it on multiple websites. So I guess really, this is more of a math question if anything.
Also given two number I need to print out the egyptian fractions for them. (i.e) given 7/8 should print the following: (1/2)+(1/4)+(1/8). All numerators must be 1.
Looks like you've done all the heavy lifting you just need a check:
def is_practical(n):
s = set(sumsOfSublists(factorFinder(n)))
return all(i in s for i in range(1, n))
Is there any reason you are sorting the sums into a list? sets are much quicker to look up. See https://wiki.python.org/moin/TimeComplexity
I reformulate your wiki-article and hope that it is helpful to you - because as AChampion has said - you have already done all the heavy lifting ;)
n is is a practical number if:
let l = [1, 2, ... n-1] // all number smaller than n
let divs = [i for i in range(1,n) if n%i==0] // all divisors of n (I associate a factor is prime cause of the term factorization of a number, so probably you should change factor to divisor in your question)
Now you have to write all numbers of l as sum of numbers from divs, where you can use all numbers of divs one or zero times
for example n = 12 is a practical number because:
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
divs = [1, 2, 3, 4, 6]
l[0] = divs[0], l[1] = divs[1], ... , l[10] = divs[0]+divs[3]+divs[4]=1+4+6=11 // l[1] = divs[0]+divs[0] is not allowed because you may use each number of divs only once
In opposite n = 3 is not a practical number because:
l = [1, 2]
divs = [1]
l[0] = divs[0], l[1] = mööööp
Here is also a straightforward implementation of my explanation (but you can also keep the nice work you have already done!):
from itertools import combinations
def isPracticalNumber(n):
l = [i for i in range(1, n)]
divs = [i for i in range(1, n) if n % i == 0]
possibleSums = set()
for i in range(1, len(divs)+1):
combinationsOfLengthI = combinations(divs, i)
for combi in combinationsOfLengthI:
possibleSums.add(sum(combi))
return all([i in possibleSums for i in l])
if __name__ == '__main__':
print(isPracticalNumber(12)) # True
print(isPracticalNumber(3)) # False
practicalNumbers = [1, 2, 4, 6, 8, 12, 16, 18, 20, 24, 28, 30, 32, 36, 40, 42, 48, 54, 56, 60, 64, 66, 72, 78, 80, 84, 88, 90, 96, 100, 104, 108, 112, 120, 126, 128, 132, 140, 144, 150]
calculatedPracticalNumbers = [i for i in range(1, 151) if isPracticalNumber(i)]
print(len(calculatedPracticalNumbers) == len(practicalNumbers) and all([i in practicalNumbers for i in calculatedPracticalNumbers]))

Remove items from a list in Python based on previous items in the same list

Say I have a simple list of numbers, e.g.
simple_list = range(100)
I would like to shorten this list such that the gaps between the values are greater than or equal to 5 for example, so it should look like
[0, 5, 10...]
FYI the actual list does not have regular increments but it is ordered
I'm trying to use list comprehension to do it but the below obviously returns an empty list:
simple_list2 = [x for x in simple_list if x-simple_list[max(0,x-1)] >= 5]
I could do it in a loop by appending to a list if the condition is met but I'm wondering specifically if there is a way to do it using list comprehension?
This is not a use case for a comprehension, you have to use a loop as there could be any amount of elements together that have less than five between them, you cannot just check the next or any n amount of numbers unless you knew the data had some very specific format:
simple_list = range(100)
def f(l):
it = iter(l)
i = next(it)
for ele in it:
if abs(ele - i) >= 5:
yield i
i = ele
yield i
simple_list[:] = f(simple_list)
print(simple_list)
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
A better example to use would be:
l = [1, 2, 2, 2, 3, 3, 3, 10, 12, 13, 13, 18, 24]
l[:] = f(l)
print(l)
Which would return:
[1, 10, 18, 24]
If your data is always in ascending order you can remove the abs and just if ele - i >= 5.
If I understand your question correctly, which I'm not sure I do (please clarify), you can do this easily. Assume that a is the list you want to process.
[v for i,v in enumerate(a) if abs(a[i] - a[i - 1]) >= 5]
This gives all elements with which the difference to the previous one (should it be next?) are greater or equal than 5. There are some variations of this, according to what you need. Should the first element not be compared and excluded? The previous implementation compares it with index -1 and includes it if the criteria is met, this one excludes it from the result:
[v for i,v in enumerate(a) if i != 0 and abs(a[i] - a[i - 1]) >= 5]
On the other hand, should it always be included? Then use this:
[v for i,v in enumerate(a) if (i != 0 and abs(a[i] - a[i - 1]) >= 5) or (i == 0)]

Odd behavior of stacked filter() calls

So I'm getting some interesting behaviour from some filters stacked within a for loop.
I'll start with a demonstration:
>>> x = range(100)
>>> x = filter(lambda n: n % 2 == 0, x)
>>> x = filter(lambda n: n % 3 == 0, x)
>>> list(x)
[0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96]
Here we get the expected output. We have a range within a filter within a filter, and the filter conditions are stacking as we want them to. Now here comes my problem.
I have written a function for calculating the relative primes of a number. It looks like this:
def relative_primes(num):
'''Returns a list of relative primes, relative to the given number.'''
if num == 1:
return []
elif is_prime(num):
return list(range(1, num))
result = range(1, num)
for factor in prime_factors(num):
# Why aren't these filters stacking properly?
result = filter(lambda n: n % factor != 0, result)
return list(result)
For whatever reason, the filter is only being applied to the LAST factor in the list acquired from prime_factors(). Example:
>>> prime_factors(30)
[2, 3, 5]
>>> relative_primes(30)
[1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24, 26, 27, 28, 29]
We can see that no multiples of 2 or 3 were removed from the list. Why is this happening? Why does the above example work, but the filters in the for loop don't?
In Python 3.x, filter() returns a generator instead of a list. As such, only the final value of factor gets used since all three filters use the same factor. You will need to modify your lambda slightly in order to make it work.
result = filter(lambda n, factor=factor: n % factor != 0, result)
The evaluation of the iterators is lazy. All filters will be evaluated only in the statement
return list(result)
By that time, the value of factor is the last prime factor. The lambda functions only contain a reference to the local name factor and will use whatever value is assigned to that name at the time of execution.
One way to fix this is to convert to a list in every iteration.
As a sidenote, a much easier implementation of this function is
from fractions import gcd
def relative_primes(n):
return [i for i in range(1, n) if gcd(n, i) == 1]
Edit: If you are after performance instead of simplicity, you can also try this one:
def relative_primes(n):
sieve = [1] * n
for i in range(2, n):
if not sieve[i] or n % i:
continue
sieve[::i] = [0] * (n // i)
return list(itertools.compress(range(n), sieve))
If I understood you correctly and Two integers are relatively prime if they share no common positive factors (divisors) except 1. Using the notation to denote the greatest common divisor, two integers a and b are relatively prime if gcd(a,b)==1. then you can use the fractions module in the following way.
from fractions import gcd
num = 30
relative_primes = filter(lambda x: gcd(x,num) == 1, xrange(1,num))

Categories

Resources