I have to replace in a list the multiples of 5 by the number + x. For example, if I have the list [1,3,5,7,9,9,11,13,15,17,19,21,23,25,27,29], the result has to be [1,3,5x,7,9,11,13,15x,17,19,21,23,25x,27,29]. I have tried to develop the script but it doesn't work, can anyone help me?
numbers = list (range(1,31))
odds = [number for number in numbers if number % 2 == 1]
print(odds)
for index, value in enumerate(odds):
if value%5==0:
odds[index] = '5x'
print(odds)
We can solve your problem by using the value variable, which stores the current number. We just need to reference this variable when setting the current element to add to "x", like this:
odds[index] = str(value) + "x"
Notice the need to cast value as a string, as we cannot concatinate an integer and a string without creating a touple.
You can make your code much simpler:
numbers = range(1, 31, 2)
res = [str(i) + 'x' if i%5 == 0 else i for i in numbers]
print(res)
Result:
[1, 3, '5x', 7, 9, 11, 13, '15x', 17, 19, 21, 23, '25x', 27, 29]
Explanation:
numbers = range(1, 31, 2)
This creates an iterable with odd numbers from 1 to 29 without having to do:
numbers = list(range(1,31))
odds = [number for number in numbers if number % 2 == 1]
which is redundant. The syntax for the range function is range(start, stop, step), so for odd numbers from 1 to 30, it'll be range(1, 31, 2) which will give 1, 3, 5, 7, and so on.
res = [str(i) + 'x' if i%5 == 0 else i for i in numbers]
I'm assuming you know how to use list comprehensions since you've used it in your code. The above line of code simply searches for a value that is divisible by 5 and adds an x to this value, else it simply adds i to the list.
You can also use f-strings instead of str(i) + x (as Stuart suggests under Jensen's answer):
res = [f'{i}x' if i%5 == 0 else i for i in numbers]
Related
write a python program to print sum of 3 consecutive numbers in a range in a list. for example we take input n = 8 so the program will print
[1+2+3,2+3+4,3+4+5,4+5+6+,5+6+7,6+7+8]
means the output should be
=[6,9,12,15,18,21]
i am new in programming, my code is:-
arr=[]
N=int(input("enter the value of N"))
def lst(arr):
for i in range(N):
x=[i]+[i+1]+[i+2]
arr.append(x)
lst(arr)
print(arr)
This will give you the output you are looking for. It starts indexed at 1 instead of 0 and calls sum on the lists you are creating in each iteration.
Edit: as pointed out in the comments, creating these lists is unnecessary you can just do a sum.
arr=[]
N=int(input("enter the value of N"))
def lst(arr):
for i in range(1, N - 1):
x = (i) + (i + 1) + (i + 2) # for ease of reading
arr.append(x)
lst(arr)
print(arr)
Using list comprehension - given a list and a length of interest lgt:
l = list(range(1, 9))
lgt = 3
print([sum(l[i-lgt:i]) for i in range(lgt, len(l) + 1)])
OUTPUT
[6, 9, 12, 15, 18, 21]
Why can't you use list comprehension,
In [1]: [(i+1) + (i+2) + (i+3) for i in range(7)]
Out[1]: [6, 9, 12, 15, 18, 21, 24]
def factorList(num):
listOfFactors = []
for i in range <= num:
if num / i == 0:
listOfFactors.append(i)
print(listOfFactors)
factorList(36)
I want the function to go through each number between 1 and the number input until it finds a factor and adds it to a list
range() is a function (it needs parens), and it starts at zero, rather than 1...
You seem to have tried to combine range with a while loop logic, like so
i = 1
while i <= num:
# if ... append ...
i += 1
But you can do the same with list-comprehension
def factorList(num):
return [i for i in range(1, num+1) if num % i == 0]
print(factorList(36))
Output
[1, 2, 3, 4, 6, 9, 12, 18, 36]
side-note: For factorization, you only need to loop up to the square-root of the number.
range() is a function that returns a sequence of numbers, so you need to call it like a function.
for i in range(num):
See some documentation here: https://www.w3schools.com/python/ref_func_range.asp
What the code does: Takes a Python list of integers as input and searches for a 'symmetrical' inner-portion of the list.
Examples of what i want:
symmetrical_sum([10,11,12,11,12]) == ([11, 12, 11], 34)
symmetrical_sum([9,99,88,8,77,7,77,8,88,10,100]) == ([88, 8, 77, 7, 77, 8, 88], 353)
symmetrical_sum([10,8,7,5,9,8,15]) == ([8, 7, 5, 9, 8], 37)
Symmetry occurs if the value of the ith element from the start of the list is equal to the value of the ith element from the end of the list.
My Code:
def symmetrical_sum(a):
#extract duplicate value
dupe = [x for n, x in enumerate(a) if x in a[:n]]
#if no duplicate values found, do the following:
if dupe == []:
middle = float(len(a))/2
if middle % 2 != 0:
sym = a[int(middle - .5):int(middle + .5)]
ans = a[int(middle - .5)]
tuple1 = (sym,ans)
elif middle % 2 == 0:
sym = a[int(middle - 1):int(middle + 1)]
ans = sum(a[int(middle - 1):int(middle + 1)])//2
tuple1 = (sym,ans)
return tuple1
else:
d_to_i = int("".join(map(str, dupe))) #convert duplicate value to integer
p1 = a.index(d_to_i) #get index of first duplicate
p2 = a.index(d_to_i, p1+1) #get index of second duplicate
sym = a[p1:p2+1] #[symmetrical-portion]
ans = sum(sym) #sum-of-symmetrical-portion
tuple2 = (sym, ans)
return tuple2
My code works but it would be great if someone can post a way shorter solution for efficiency purposes, please.
x = [10,11,12,11,12]
output = [(x[n:-n],sum(x[n:-n])) for n in range(len(x)) if x[n] == x[-n-1]]
#this will output 3 cases: Symmetry regardless of even/odd elements. OR no symmetry for odd. (middle index)
if output == []:#even number of elements with no symmetry at all
pass
if len(output[0][0]) == 1: #odd number of elements with no symmetry at all
pass
print(output[0])
I hope this helps. I don't really understand what you do when no symmetry is detected. output will return all lists of symmetry and their sums including if there is no symmetry but odd number of elements. Not particularly sure if this is the optimal way to do what you want.
I'm trying to find and return the single even integer in a list of odd integers or the sole odd integer in a list of even integers. My code works, however, if the length of the list for odd integers is even, it returns the first number in the list instead of the even integer. Any help is appreciated. Code below:
even = [2, 4, 6, 8, 10, 12, 14, 2091] #2091 is the outlier and len(x) = 8
odd = [1, 3, 5, 7, 9, 11, 13, 4720] #4720 is the outlier and len(x) = 8
def find_outlier(x):
# Determine if list is even and length of list is odd
if sum(x) % 2 != 0 and len(x) % 2 != 0:
for x in x:
if x % 2 != 0:
return x
# Determine if list is even and length of list is even
elif sum(x) % 2 != 0 and len(x) % 2 == 0:
for x in x:
if x % 2 != 0:
return x
# Determine if list is odd and length of list is odd
elif sum(x) % 2 == 0 and len(x) % 2 != 0:
for x in x:
if x % 2 == 0:
return x
# Determine if list is odd and length of list is even (PROBLEM)
elif sum(x) % 2 == 0 and len(x) % 2 == 0:
for x in x:
if x % 2 == 0:
return x
print (find_outlier(even))
print (find_outlier(odd))
Below is the correct solution to the problem reformatted from Dmitri's solution:
def find_outlier(x):
odd = [i for i in x if i % 2 != 0]
even = [i for i in x if i % 2 == 0]
return odd[0] if len(odd) < len(even) else even[0]
Why do you care about the length at all? Here is much simpler solution:
def find_outliner(a):
if a[0] % 2 != a[1] % 2:
return a[0] if a[2] % 2 == a[1] % 2 else a[1]
for i in a:
if i % 2 != a[0] % 2:
return i
How does it work?
There should be at least three elements in the list, otherwise the problem does not make much sense
If the first two elements have different parity, check which element is wrong based on third (if the second and the third have the same parity, the first is the wrong one, otherwise - the second is the wrong one)
If the first two elements have the same parity, that means that parity of the first (and the second) element is the correct parity for list. Thus, the element with different parity is what we are looking for.
The problem is you are summing the list trying to use that to determine whether the list is primarily odds or evens. That doesn't work because the sum of a list of evens is even, but a sum of odds will be even or odd based on the number of items in the list.
Instead, just keep track of the last even and odd in the list and whether you have seen more than one of a given type. And as soon as you have two evens or two odds you can assume the outlier is the other one.
Also, using sum() and len() in each IF clause can be incredibly inefficient because you are doing it multiple times.
Just an alternative, collecting the evens and odds in two lists and then using the smaller list.
def find_outlier(x):
evenodd = [], []
for v in x:
evenodd[v & 1].append(v)
return min(evenodd, key=len)[0]
Demo:
>>> for x in [2, 4, 6, 8, 10, 12, 14, 2091], [1, 3, 5, 7, 9, 11, 13, 4720]:
print(find_outlier(x))
2091
4720
I'm trying to find the avg of list but only when n >= 10 (two digit numbers, my original list is limited to 100).
Here's what I have right now:
# Calculate average of all two-digit numbers (10-99)
grade_list = [10, 11, 12, 13, 14, 15]
def calcAvg(grade_list):
while n > 10:
total = sum(grade_list)
n = total % len(grade_list)
print_list = n
return print_list
I get that I have to find the total sum of the list when n > 10 and then dividing by the length (only > 10, my original list has single digit elements, so I'd like to avoid them).
But when I run it, I get an error saying: local variable 'n' referenced before assignment
Any help on how to structure this function to achieve the end results (sum/total of only 2-digit elements = avg)
Thanks!
I'd either collect the good grades and use sum/len, or use the mean function:
>>> grade_list = [1, 2, 10, 11, 12, 13, 14, 15]
>>> good = [g for g in grade_list if g > 10]
>>> sum(good) / len(good)
13.0
>>> import statistics
>>> statistics.mean(g for g in grade_list if g > 10)
13.0
def calcAvg(grade_list):
my_list = []
total, count = 0,0
for n in grade_list:
if 10 <= n <= 99:
total += n
if not total:
return None
return total/count
Here is a clean way of doing it:
def calc_avg(lst):
filtered_lst = filter(lambda x: 10 < x < 100, lst)
return sum(filtered_lst) / len(filtered_lst)
So you should use a for loop instead of a while loop. Instead of having two for loops and making a new list, you could just account for the sum inside the first for loop. I demonstrate this below.
def calcAvg(grade_list):
sum = 0;
count = 0;
for n in grade_list:
if 10 <= n <= 99:
sum = sum + n
count = count + 1
return sum/count
I think you should manually go over the code step by step and try to understand what is wrong. Meanwhile this may give you some hints
# Calculate average of all two-digit numbers (10-99)
def calcAvg(alist):
count=total=0
for i in alist:
if 9 < i < 100:
total += i
count += 1
return total/count
Since Python 3.4 there is a statistics module.
So you just need to filter out numbers in range <10,100), for example with a list comprehension, and then pass this filtered list to the mean function. Simple as that.
from statistics import mean
numbers = [1, 20, 30, 50]
mean([n for n in numbers if n >= 10 and n < 100])
>>> 33.333333333333336
You could do this fairly simply with a list comprehension
>>> grades = [1, 2, 10, 11, 12, 13, 14, 15, 120, 122, 320]
>>> lst = [v for v in grades if 10 <= v < 100]
>>> sum(lst)/len(lst)
12