I've met a question about list comprehension.
num1 = [5,10,15]
num2 = [i**2 if i == 10 else i-5 if i < 7 else i+5 for i in num1]
why num2 is num2 = [0,100,20]?
How does the result get?
Read it as:
num2 = [i**2 if i == 10
else i-5 if i < 7
else i+5
for i in num1]
5 is not equal to 10, but it is less than 7, so it yields 5 - 5 (i.e. 0)
10 is equal to 10, so it yields 10 ** 2 (i.e. 100)
15 is not equal to 10, not equal to 7, thus we use the default case, so it yields 15 + 5 (i.e. 20)
This list comprehension is exactly equivalent to:
num2 = []
for i in num1:
if i == 10:
num2.append(i**2)
else:
if i < 7:
num2.append(i-5)
else:
num2.append(i+5)
Related
I want to create a dict with lists as values, where the content on the lists depends on whether or not the key (numbers 1 to 100) is dividable by 3,5 and/or 7
The output would be like this:
{
1: ['nodiv3', 'nodiv5', 'nodiv7'],
3: ['div3', 'nodiv5', 'nodiv7'],
15: ['div3', 'div5', 'nodiv7'],
}
Similar questions where about filtering the list/values, not creating them.
dict_divider = {}
for x in range(0,101):
div_list= []
if x % 3 == 0:
div_list.append('div3')
else:
div_list.append('nodiv3')
if x % 5 == 0:
div_list.append('div5')
else:
div_list.append('nodiv5')
if x % 7 == 0:
div_list.append('div7')
else:
div_list.append('nodiv7')
dict_divider[x] = div_list
This works just fine, but is there a way to do this with a pythonic one-/twoliner?
Something along like this: d = dict((val, range(int(val), int(val) + 2)) for val in ['1', '2', '3'])
Pythonic is not about one or two liners. In my opinion is (mainly) about readability, perhaps this could be considered more pythonic:
def label(n, divisor):
return f"{'' if n % divisor == 0 else 'no'}div{divisor}"
def find_divisors(n, divisors=[3, 5, 7]):
return [label(n, divisor) for divisor in divisors]
dict_divider = {x: find_divisors(x) for x in range(1, 101)}
print(dict_divider)
You don't actually need to do all these brute-force divisions. Every third number is divisible by three, every seventh number is divisible by seven, etc:
0 1 2 3 4 5 6 7 8 9 ... <-- range(10)
0 1 2 0 1 2 0 1 2 0 ... <-- mod 3
0 1 2 3 4 5 6 7 8 9 ... <-- range(10)
0 1 2 3 4 5 6 0 1 2 ... <-- mod 7
So the best approach should take advantage of that fact, using the repeating patterns of modulo. Then, we can just zip the range with however many iterators you want to use.
import itertools
def divs(n):
L = [f"div{n}"] + [f"nodiv{n}"] * (n - 1)
return itertools.cycle(L)
repeaters = [divs(n) for n in (3, 5, 7)]
d = {x: s for x, *s in zip(range(101), *repeaters)}
There is actually a one liner that isnt even that complicated :)
my_dict = {}
for i in range(100):
my_dict[i] = ['div' + str(n) if i % n == 0 else 'nodiv' + str(n) for n in [3,5,7]]
you could write a second loop so that you only have to write if...else only once
dict_divider = {}
div_check_lst = [3, 5, 7]
for x in range(0,101):
div_list= []
for div_check in div_check_lst:
if x % div_check == 0:
div_list.append(f'div{str(div_check)}')
else:
div_list.append(f'nodiv{str(div_check)}')
dict_divider[x] = div_list
or
dict_divider = {x:[f'{'no' * x % div_check != 0}div{str(div_check)}' for x in range(0,101) for div_check in div_check_lst]}
I'm a beginner and I tried this code to list the sum of all the multiples of 3 or 5 below 100, but it gives a wrong answer and I don't know why.
result = 0
result2 = 0
som = 0
sum2 = 0
below_1000 = True
while below_1000:
result = result+3
if result < 1000:
som += result
else:
below_1000 = False
below_1000 = True
while below_1000:
result2 = result2+5
if result2 < 1000:
sum2 += result2
else:
below_1000 = False
final_result = som+sum2
print(final_result)
Since you first loop over multiples of 3, then again over multiples of 5, you are double-counting a lot of values, specifically values that are multiples of both 3 and 5 (for example 15 or 60).
To write this manually, you can use a for loop over range
total = 0
for i in range(1000):
if i % 3 == 0 or i % 5 == 0:
total += i
>>> total
233168
A more concise way to do this same thing is using a generator expression within the sum function
>>> sum(i for i in range(1000) if i % 3 == 0 or i % 5 == 0)
233168
I am trying to solve a problem where I have to enter several integers as an input (seperated by a whitespace), and print the integer that is the sum of all the OTHER integers.
So e.g.:
1 2 3 would give: 3, because 3 = 1 + 2
1 3 5 9 would give: 9, because 5 + 3 + 1 = 9
This is the code I currently have:
x = input().split(" ")
x = [int(c) for c in x]
y = 0
for i in range(len(x)-1):
y += x[i]
del x[i]
z = sum(x)
if y == z:
print(y)
break
else:
x.insert(i,y)
As the output, it just gives nothing no matter what.
Does anyone spot a mistake? I'd be ever greatful as I'm just a beginner who's got a lot to learn :)
(I renamed your strange name x to numbers.)
numbers = input().split()
numbers = [int(i) for i in numbers]
must_be = sum(numbers) / 2
if must_be in numbers:
print(int(must_be))
The explanation:
If there is an element s such that s = (sum of other elements),
then (sum of ALL elements) = s + (sum of other elements) = s + s = 2 * s.
So s = (sum of all elements) / 2.
If the last number entered is always the sum of previous numbers in the input sequence. Your problem lies with the x.insert(i, y) statement. For example take the following input sequence:
'1 2 5 8'
after the first pass through the for loop:
i = 0
z = 15
x = [1, 2, 5, 8]
y = 1
after the second pass through the for loop:
i = 1
z = 14
x = [1, 3, 5, 8]
y = 3
after the third pass through the for loop:
i = 2
z = 12
x = [1, 3, 8, 8]
y = 8
and the for loop completes without printing a result
If it's guaranteed that one of the integers will be the sum of all other integers, can you not just sort the input list and print the last element (assuming positive integers)?
x = input().split(" ")
x = [int(c) for c in x]
print(sorted(x)[-1])
I think this is a tricky question and can be done in quick way by using a trick
i.e create a dictionary with all the keys and store the sum as value like
{1: 18, 3: 18, 5: 18, 9: 18}
now iterate over dictionary and if val - key is in the dictionary then boom that's the number
a = [1, 3, 5, 9]
d = dict(zip(a,[sum(a)]*len(a)))
print([k for k,v in d.items() if d.get(v-k, False)])
here i am getting multiplication table using print statement.
userNum = int(input("enter a number:"))
def multiply(n):
comp = 10
count = 0
while comp > count:
count+=1
z = n*count
y = "{1} * {2} = {0}".format(z,n,count)
print(y)
multiply(userNum)
here i am getting only 5 *1 = 5.it does not execute other despite using loops
userNum = int(input("enter a number:"))
def multiply(n):
comp = 10
count = 0
while comp > count:
count+=1
z = n*count
y = "{1} * {2} = {0}".format(z,n,count)
return y
a = multiply(userNum)
print(a)
This is because in Python, the return statement automatically exits the function, because a function can only return one item. Hence, in the second scenario, once y was returned, it exited the function, so it only printed the first item in the while loop.
In response to your comment
"so how to return loops in function without print statement?any
solution?"
You could write a nested loop in order to loop over a list, which stores the items returned by the function. For example:
userNum = int(input("enter a number:"))
y_values = []
def multiply(n):
comp = 10
count = 0
while comp > count:
count+=1
z = n*count
y = "{1} * {2} = {0}".format(z,n,count)
y_values.append(y)
multiply(userNum)
You can then loop over the list to print the items:
for y in y_values:
print(y)
OUTPUT, as expected:
enter a number:5
5 * 1 = 5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
5 * 6 = 30
5 * 7 = 35
5 * 8 = 40
5 * 9 = 45
5 * 10 = 50
This question already has answers here:
Adding odd numbers in a list
(6 answers)
Closed 5 years ago.
I want to sum my odd numbers, so if I enter num=7 or 8 it counts: 1, 3, 5, 7 : Correct, but I want to sum them. So the answer for 7 and 8 should be 16 (1 + 3 + 5 + 7 = 16)
Or if I enter num=9 then I expect 1 + 3 + 5 + 7 + 9 = 25
I must use While for this calc.
num = int(input("Insert number: "))
sum = 1
num += 1
while sum < num:
print(sum)
sum = sum + 2
You can use the built-in sum() function like this:
num = int(input("Insert number: "))
s = sum(range(1, num+1, 2))
range() takes start (inclusive), end (exclusive), and step (In our case: start=1, end=num+1 and step=2)
Output:
>>> num = 9
>>> s = sum(range(1, num+1, 2))
>>> s
25
If using while is a requirement, then you can achieve the same result with:
>>> s = 0
>>> i = 1
>>> while i < num + 1:
... if i % 2: # Or: i % 2 != 0, which means we only consider odd nums
... s += i
... i += 1
...
>>> s
25