Even numbers a list? - python

How do I create a list and only extract or search out the even numbers in that list?
Create a function even_only(l) that takes a list of integers as its only argument. The
function will return a new list containing all (and only) the elements of l which are evenly divisible by 2. The original list l shall remain unchanged.
For examples, even_only([1, 3, 6, 10, 15, 21, 28]) should return [6, 10, 28], and
even_only([1, 4, 9, 16, 25]) should return [4, 16].
Hint: Start by creating an empty list, and whenever you encounter an even number in it, add it to your list, then at the end, return your list.

"By hand":
def even_only(lst):
evens = []
for number in lst:
if is_even(number):
evens.append(number)
return evens
Pythonic:
def even_only(iter):
return [x for x in iter if is_even(x)]
Since it's homework, you can fill in the is_even function.

Simplest way would be to do what you posted in a comment -- iterate through the input list to find digits evenly divisible by 2, and add them to the return list if so.
The list.append(x) function will help you add an item to a list.
Also as mentioned, look at using the modulo operation to determine if a number is divisible by 2...

The best way to do this (as a beginner) is probably a comprehension list. Since this is a homework, I won't do it for you, but here is the syntax :
[x for x in your_list if (your condition)]
You just have to replace (your condition) with what fits well (basically, exactly what you described).
P.S. I know some people may say comprehension lists are a bit advanced for a beginner, but I think it is not a concept too hard to catch and extremely useful.

>>> a = [1, 3, 6, 10, 15, 21, 28]
>>> b = [i for i in a if i%2 ==0 ]
>>> b
[6, 10, 28]
>>> a
[1, 3, 6, 10, 15, 21, 28]

>>> even_only = lambda seq : [ x for x in seq if str(x)[-1] in "02468" ]
>>> even_only([1, 3, 6, 10, 15, 21, 28])
[6, 10, 28]

Use the filter function to do this in a functional way:
>>> even_filter = lambda x: not x % 2
>>> result = filter(even_filter, [0, 1, 2, 3, 4])
>>> assert result == [0, 2, 4]
Edit: updated with the correct parity of zero per Vincent's comment.

I recently had this issue and used:
list=[1,2,3,4,5,6] #whatever your list is, just a sample
evens=[x for x in list if np.mod(x,2)==0]
print evens
returns [2,4,6]

for every element in list, if element of list modulo is 0 then number is even
initial_list = [1,22,13,41,15,16,87]
even_list = [ x for x in initial_list if x % 2 == 0]
even_list
# [22, 16]

Seems a bit late.But whats given below, works fine for me:
def even_list(*args):
# Returns the even numbers in the list
return [x for x in args if (x % 2 == 0)]
even_list(1,2,3,4,5,6,7,8)
[2, 4, 6, 8]

Related

Invert the list by exchanging the first and last element, the second and second last, and so on

So Basically the task is to invert the List by changing the first element with the last one, the second one with the second last etc...
This is what i tried, but nothing happend in the end. Do you have any ideas whats not working here or what different approach i should try?
list=[3,6,9,12,15,18,21,24,27,30]
y = 0
x = len(list)-1
while y <= x:
for i in list:
list[y],list[x]=list[x],list[y]
y+=1
x-=1
for i in list:
print(i)
All the other solutions are good approaches, but if you were specifically
asked to write the logic for inverting the list by changing the first element with last element and so on..here,
y = 0
x = len(list)-1
while y < x:
list[y],list[x]=list[x],list[y]
y+=1
x-=1
for i in list:
print(i)
You can do something like this:
def reverse(lst):
# Iterate over the half of the indexes
for i in range(len(lst) // 2):
# Swap the i-th value with the i-th to last value
lst[i], lst[len(lst)-1-i] = lst[len(lst)-1-i], lst[i]
lst = [1, 2, 3, 4, 5]
reverse(lst)
print(lst) # Outputs [5, 4, 3, 2, 1]
lst = [1, 2, 3, 4]
reverse(lst)
print(lst) # Outputs [4, 3, 2, 1]
You can use the reverse() function:
l = [3,6,9,12,15,18,21,24,27,30]
l.reverse()
You can do as follow:
l=[3,6,9,12,15,18,21,24,27,30]
new_l=l[::-1]
The following will invert the order of a list:
>>> l = [3,6,9,12,15,18,21,24,27,30]
>>> l[::-1]
Out[11]: [30, 27, 24, 21, 18, 15, 12, 9, 6, 3]
You can use this code :
for i in sorted(list,reverse=True):
print(i)

Why list comprehension doesn't work the same as code without comprehension?

I tried to create a simple function to remove duplicates from the list.
x = [7, 7, 5, 6, 8, 9, 9, 0]
for n, i in enumerate(x):
if i in x[n + 1:]:
x.remove(i)
print(x)
Output:
[7, 5, 6, 8, 9, 0]
This code works fine as far as I know.
But when I'm trying to convert it in comprehension list form, I'm getting wrong output:
def unique_list(lst):
return [lst.remove(i) for n, i in enumerate(lst) if i in lst[n + 1:]]
x = [7, 7, 5, 6, 8, 9, 9, 0]
print(unique_list(x))
Output:
[None, None]
So, the question is - why the output is different?
a = [1, 2, 3]
deleted = a.remove(1)
print(deleted)
# returns None
print(a)
# returns [2, 3]
.remove() changes the list in place and returns None
Your two ways of writing the functionality of set(x) are not identical. While the first is using a side-effect of x.remove(..) to "return" your modified list in place, the second form returns a newly created list.
The elements of that list are formed by what is returned by the expression lst.remove(i), which is None as Manuel already has pointed out in their answer.
You receive [None, None] because your code calls lst.remove 2 times. So your function unique_list could be called count_duplicates, just with a peculiar output format (with the length of a list of None encoding the result instead of a straightforward int).

Iterative list with "in range" function?

I'm still pretty new to this website and to python. So, please forgive my question possibly not being specific enough and the possibility of there already being an answer that I haven't found yet.
Basically, I am having trouble with for loops in python.
I want to create lists using the in range() function. Each successive list should set with the next number. For example
[1,2,3,4,5]
[2,3,4,5,6]
[3,4,5,6,7]
I want also the lists that are produced to be of equal length: for example, 5 numbers, 6 numbers or 7 numbers, etc.
l=[]
for i in range (1,10):
for a in range (i):
l.append (i)
print (l[:5])
result is:
[1]
[1, 2]
[1, 2, 2]
[1, 2, 2, 3]
[1, 2, 2, 3, 3]
and then it just repeats with 3. However, I want the next line two start with a new number, so 2 then the next line 3, etc.
I would greatly appreciate your help or at least a hint in the right direction !
If this question has already been answered, I would also appreciate having the link for the respective article.
Start over. Code one or two lines at a time. Print out variables to trace their values. Do not write more code until you know that the current code does what you need. A significant portion of your problem is that you tried to write too much code in one pass, more than you (yet) know how to handle.
Let's start here:
l=[]
for i in range (1,10):
...
Although you clearly state that you want a new starting point at each iteration, you initialize l only once. This means that it will accumulate all of the values you append to it for the entire run of the program, rather than giving you a new list each time.
for a in range (i):
How does this support anything that you're trying to do? You will iterate once, then twice, then 3 times ... what part of your program is repeated in this fashion? You clearly state that you want each list to be of the same length, but then you go out of your way to ensure that you accumulate an ever-increasing list on each completion of this inner loop.
Does this get you moving?
Hey Christopher try this.
for i in range (0,4):
l=[]
for j in range (1+i,6+i):
l.append (j)
print(l)
I think what you're trying to do probably looks something like this:
my_lists = []
for i in range(10):
some_list = []
for j in range(5):
some_list.append(i + j)
print(some_list)
my_lists.append(some_list)
# or if you're being fancy,
# my_lists = [list(range(i, i + 5)) for i in range(10)]
I wouldn't worry too much about the ways to shorten and/or optimise the various
bits of it for now. This gives you a nice list my_lists of all the smaller
lists generated. Does that help you? I'd make sure you understand what's going
on in each loop, and why everything's structured the way it is.
(side note: the sum of the first three values of each list
is given by a fairly straightforward arithmetic progression, so if you need to
calculate it efficiently you'd be better off looking for an algebraic closed
form.)
You could write a function like this one:
def makelists(start, end, n):
sequence = [i for i in range(start, end + 1)]
if n == 1:
print(sequence)
else:
print(sequence)
for i in range(1, n):
sequence = list(map(lambda x: x + 1, sequence))
print(sequence)
makelists(1, 5, 3)
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
For other inputs:
makelists(3, 10, 7)
[3, 4, 5, 6, 7, 8, 9, 10]
[4, 5, 6, 7, 8, 9, 10, 11]
[5, 6, 7, 8, 9, 10, 11, 12]
[6, 7, 8, 9, 10, 11, 12, 13]
[7, 8, 9, 10, 11, 12, 13, 14]
[8, 9, 10, 11, 12, 13, 14, 15]
[9, 10, 11, 12, 13, 14, 15, 16]

Summing elements at the beginning with the elements at the end of a list

Given a list of numbers, create a new list of numbers such that the first and last numbers are added and stored as the first number, the second and second-to-last numbers are stored as the second number, and so on
num_list = [1,2,3,4,5,6]
num_list2 = [num_list[-1] + num_list[0], num_list[-2] + num_list[1],
num_list[-3] + num_list[2]]
print(num_list2)
output is [7,7,7]
I got the correct output this way but I am sure this is not an efficient way to do it. Is there a better way? I also am supposed to check for even and odd length of the list and if its an odd number of integers, add the central integer in the original list to the end of the new list but don't know how I would go about doing this
I think this is more efficient, i just simply did a for loop:
num_list2 = []
num_list = [1,2,3,4,5,6]
for i in range(round(len(num_list)/2)):
num_list2.append(num_list[i]+num_list[-(i+1)])
print(num_list2)
Output:
[7, 7, 7]
Let us using reversed
[x + y for x, y in zip(num_list, list(reversed(num_list)))][:len(num_list)//2]
Out[406]: [7, 7, 7]
Here's an inefficient[1], but clear way of doing this:
from itertools import zip_longest # or izip_longest in Python2
lst = [1,2,3,4,5,6]
chop_index = len(lst) // 2 # (or +1, depending on how you want to handle odd sized lists)
lh, rh = lst[:chop_index], lst[:chop_index-1:-1]
print(lh, rh) # To see what's going on in the "chopping"
sums = [x + y for (x,y) in zip_longest(lh, rh, fillvalue=0)]
print(sums)
You could improve it by using islice and reversed iterators, or use index math exclusively.
Output:
lst = [1,2,3,4,5,6] => [7, 7, 7]
lst = [1,2,3,4,5,6,7] => [8, 8, 8, 4]
[1] This makes two copies of the list parts. For long lists this is silly, and you shouldn't use this method. It was mostly written to highlight zip_longest's fillvalue optional argument.
Using itertools.islice on a generator:
from itertools import islice
num_list = [1,2,3,4,5,6]
generator = (x + y for x, y in zip(num_list, num_list[::-1]))
print(list(islice(generator, len(num_list)//2)))
# [7, 7, 7]
You can use the following method, which is compatible with asymmetrical list.
def sum_start_end(list_):
result = [x + y for x, y in zip(list_, list_[::-1])][:len(list_) // 2]
if len(list_) % 2 != 0:
result.append(list_[len(list_) // 2])
return result
so for a symmetric list
>>> num_list = [1, 2, 3, 4, 5, 6]
>>> sum_start_end(num_list)
[7, 7, 7]
and for asymmetric list
>>> num_list = [1, 2, 3, 4, 5, 6, 7]
>>> sum_start_end(num_list)
[8, 8, 8, 4]
It's simpler than you imagine.
Just observe your manual attempt and try to infer from it. We can simply do
x = len(num_list)//2 + len(num_list)%2
for i in range(x):
sumBoth = num_list[i] + num_list[-i-1]
num_list2.append(sumBoth)
or with a simpler one-liner
num_list2 = [ num_list[i] + num_list[-i-1] for i in range(len(num_list)//2+len(num_list)%2)]
This works for even as well as odd lengths because of the len(num_list)%2 at the end in the range.

How do I raise every element in a list to its corresponding index number?

So if the input is [3, 2, 5], the output would be [1, 2, 25], and if the input was [5, 10, 20], the output would be [1, 10, 400] (5^0, 10^1, 20^2)
a very simple way is use a loop like following
for i in range(0,len(input)):
print(input[i]**i)
Your own solution is neither correct nor pythonic . Here is your code will fail :
So if my input is :
3 2 5 3 2 5
output should be :
[1, 2, 25, 27, 16, 3125]
But your code will give :
[1, 2, 25, 1, 2, 25]
Because after 3,2,5 when again 3 comes in the list then index(i) will choose first 3 in the list not second 3 or third or any. So index will always choose first appear numbers and hence you will get the wrong output.
The right way is use enumerate :
print([j**i for i,j in enumerate([int(i) for i in input().split()])])
output:
[1, 2, 25, 27, 16, 3125]
You could just use a map between your input list and a range.
def raise_power(input_list):
return list(map(lambda x,y: x**y, input_list, range(len(input_list))))
Or a more straightforward way (suggested by #roganjosh) to put it could be :
def raise_power(input_list):
return [i**x for x, i in enumerate(input_list)]
Both have no significant difference in computation time. (see comments)
You need to split the input into a list, then use enumerate to get the index position and the value. Since the value will be a string, use int to convert and then raise it to the power.
x = input('Enter the list of numbers : ')
y = [int(i) for i in x.split(',')]
print ([int(a)**i for i,a in enumerate(y)])
Code output will be:
Enter the list of numbers : 3,2,5
[1, 2, 25]
I actually figured it out myself! I'm sure you are all very proud. The below code will produce the output I'm looking for. Thank you though!
firstlist = [int(x) for x in input().split()]
newlist = [i ** (int(firstlist.index(i))) for i in firstlist]

Categories