Scenario if in input numbers are repeat - python

Code:
n = int(input("Type n: "))
def some_function(n):
numbers, numbers_sum = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 45
while True:
digit = n % 10
n //= 10
if digit in numbers:
numbers.remove(digit)
numbers_sum -= digit
else:
break
return numbers_sum
print(some_function(n))
Program needs to print the sum of numbers that are not found in the input.
I covered the scenario when numbers are not repeating and for this scenario if the input is 234567890 output is 1 .
But don't have an idea for scenario when numbers are repeating.Etc. if the input is 22334567890 or 223344556677889900 output still needs to be 1 but it's not.
P.S.
I can't do it with strings.
I know 0 doesn't make difference because we are doing with - and +.

the easier way to do it is to transform it to a string and do set operations
>>> n=22334567890
>>> numbers=set("123456789")
>>> numbers-set(str(n))
{'1'}
>>>
and then transform back to integers
>>> sum(map(int,{'1'}))
1
>>>
if you don't want the string conversion, just make a function that give you the digits of the numbers and do the same
>>> def digits(n): #this is a generator function
if n==0:
yield 0
while n:
n,d = divmod(n,10)
yield d
>>> n=22334567890
>>> numbers=set(range(10))
>>> numbers
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> list(digits(n))
[0, 9, 8, 7, 6, 5, 4, 3, 3, 2, 2]
>>>
>>> numbers - set(digits(n))
{1}
>>> sum({1})
1
>>>

I solved it.Code:
n, finish = int(input("Type n: ")), 0
dig_list, num_list = [], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def sum(n):
while n > 0:
digit = n % 10
n //= 10
dig_list.append(digit)
for i in range (0, 11):
if i in dig_list:
num_list.remove(i)
return num_list
for e in (sum(n)):
finish += e
print(finish)
Purpose of code.
Explanation:
First, we create 2 lists.
The first one(dig_list) has no elements and there we are gonna put all digits of input(n).
The second list is a list of numbers from 0 to 9(num_list).
Then we put all digits of n in the first list.Then using for loop we go through the first list.If numbers from 0 to 9 are found in the first list we remove them from the second list.
In the end, we save the sum(+) of the remaining elements of the second list to a variable sum.

Related

How to create an output list which is the sum of alternating elements from an input number_list

I'm trying to sum the even and odd-indexed elements of a list together without the use of the sum() method, but something is going wrong. I'm new to Python so help would be appreciated.
An example would be input number_list as [1, 2, 3, 4] then the output list will be [4, 6], which is from the sum of the even-numbered elements 1 and 3, and the odd-numbered elements 2 and 4 from the list number_list. Similarly, [5, 8, 3, 2, 6, 7, 1] would have an output list of [8, 10, 9, 9, 5].
This is my code:
number_list = [2, 6, 3, 5, 9, 1, 7]
res=[0, 0, 0, 0, 0, 0]
for i in range(0, len(number_list)):
if(i % 2):
res[1] += number_list[i]
else :
res[0] += number_list[i]
print("Input List: {0}\n".format(number_list))
print("Output List: {0}\n".format(res))
I think the following is what you were going for; your first attempt was definitely on target:
!/usr/bin/env python3
number_list = [2, 6, 3, 5, 9, 1, 7]
i = 0
r = [0,0]
for n in number_list:
if (i % 2) == 0:
# Even
r[0] += n
else :
# Odd
r[1] += n
i += 1
print(" Input List: {0}". format(number_list))
print("Output List: {0}". format(r))
The result is:
Input List: [2, 6, 3, 5, 9, 1, 7]
Output List: [21, 12]
There are some simplifications here, namely throwing out Python nuances and just looking at iterating over a list of numbers, determining whether they are in the even or odd position (the i index), and adding (summing) them to the base r array. Is this the most compact and optimized Python code you will encounter? No. But is it clear as to what you're trying to do - I think so.
Joe's answer is absolutely correct. However more compact answer would be..
r = [0,0]
for n, val in enumerate(number_list):
j = n % 2
r[j] += val
print(" Input List: {0}". format(number_list))
print("Output List: {0}". format(r))

How to combine two conditions using "and" in list comprehensions?

I want to return a list of sorted numbers such that odd numbers come first and even numbers come last.
Example: my_sort([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) => [1, 3, 5, 7, 9, 2, 4, 6, 8]
My solution is returning an empty list.
def my_sort(lst):
sortd_lst = sorted([xfor x in lst if x % 2 == 1 and x % 2 == 0])
return sortd_lst
You misunderstand what your code is doing.
sortd_lst = sorted([xfor x in lst if x % 2 == 1 and x % 2 == 0])
Your code is checking if a number is both even and odd, which is obviously impossible. Thus, you would get an empty list. You need to check these conditions separately.
Here is what you want:
sortd_lst = [*sorted(x for x in lst if x % 2 == 1), *sorted(x for x in lst if x % 2 == 0)]
This makes two separate sorted lists of odd and even numbers respectively, and then unpacks them into your sortd_lst.

How to check if a specific digit is in an integer

I want to check if, for example, the digit '2' is in 4059304593.
My aim is to then check if there are any of the digits 1-9 not in my integer. This is what I have tried:
for i in xrange(10):
for j in xrange(100):
num = str(i^j)
one_count = 0
two_count = 0
for k in xrange(len(num)):
if num[k] == 1:
one_count += 1
if num[k] == 2:
two_count += 1
Then my "counts" would go all the way down to nine_count, and if any of the counts are 0, then that digit isn't in 'num'. From what I've read on these sites, my script would be inefficient - can someone point out a better way?
This "digit" thing calls for a string approach, not a numeric one (reminds me of some Project Euler puzzles).
I'd create a set out of the digits of your number first (removing duplicates at the same time)
s = set(str(4059304593))
then to check for a digit:
print('2' in s)
(note that in for a set is performant)
then, to check whether s contains all the 013456789 digits:
print(s.issuperset("013456789"))
(if this must be done multiple times, it may be worth to create a set with the string, issuperset will work faster)
You could convert your number to a string, then to a set to get the unique digits.
You just have to iterate over digits in 0-9 to find the ones not present in your original number :
>>> set(map(int,str(4059304593)))
set([0, 9, 3, 4, 5])
>>> digits = _
>>> [i for i in range(10) if i not in digits]
[1, 2, 6, 7, 8]
L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
j = 0
nL = [0, 0, 0, 0, 0, 0, 0, 0, 0]
n = 1004 #number
while n:
i = n%10
nL[i] = 1
n //= 10
OUT
nL = [1, 1, 0, 0, 1, 0, 0, 0, 0, 0]
Explanation:
if nL[i] is 1, then the i-th digit is in n
Since you just want to find out which digits aren't in your number:
def not_in_number(n):
return {*range(10)} - {*map(int, {*str(n)})}
Usage:
>>> not_in_number(4059304593)
{1, 2, 6, 7, 8}
This takes the set of digits ({*range(10)}) and substracts from it the set of digits of your number ({*map(int, {*str(n)})}), created by mapping the set of digit characters to integers. If you find the {*...} notation confusing, you can always use set(...) instead, which will also work for Python 2.7+:
def not_in_number(n):
return set(range(10)) - set(map(int, set(str(n))))
Another way is using - with sets:
set('0123456789') - set(str(4059304593))
Result are all digits that aren't in your integer:
{'2', '7', '1', '6', '8'}

Rotating a list without using collection.deque

I want to make a script. The program should get some list L with values, and natural number N.
If N>0, the list's objects move N steps to left.
If N<0, the list's objects move abs(N) to the right.
If N=0 the list remain the same...
For example: For N=1 and L=[1,2,3,4,5], the output is [2,3,4,5,1].
For same list and N=-1 the output is [5,1,2,3,4]
I actually did it using collection.deque, but I want to do this with nothing but lists, for loop and 'if'.
I have problem to understand how to make the objects move.
l = input("enter list:")
N = input("enter number of rotations:")
import collections
d = collections.deque(l)
d.rotate(-N)
print d
You can use list slicing:
def rotate(L, N):
if not L or N % len(L) == 0:
return L
return L[N % len(L):] + L[:N % len(L)]
L = [1, 2, 3, 4, 5]
for N in range(-3, 4):
print(rotate(L, N))
Output:
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
[5, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 1]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
Note that if you use a list, the time complexity of a rotation is linear to the number of elements in the list in general, since you have to move all existing elements. deque.rotate(), on the other hand, is O(k), with k being the number of steps. Therefore, if you need to rotate more than once deque.rotate() is the way to go.
This works:
result = l[N % len(l):]+l[:N % len(l)]
If using numpy is an option for you, there is a method called roll, which you might want to have a look at:
import numpy as np
array = np.arange(1, 6) # 1 to 5
print array
print np.roll(array, 0)
print np.roll(array, 2)
print np.roll(array, -2)
print np.roll(array, 17)
The result is as expected:
[1 2 3 4 5]
[1 2 3 4 5]
[4 5 1 2 3]
[3 4 5 1 2]
[4 5 1 2 3]
If you're after simple lists here's how you can do it in Python 3 (based on your P2 example).
L = list(map(int, input("Enter numbers: ").split(" ")))
N = int(input("Enter how many rotations to perform: "))
print(L[N:] + L[:N])
If you don't want to create new list, you can try in-place reverse,
def reverse(nums, start, end):
i = start
j = end - 1
while i < j:
tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
i += 1
j -= 1
def rotate(nums, n):
if n == 0:
return nums
length = len(nums)
if n < 0:
n = length + n
reverse(nums, 0, n)
reverse(nums, n, length)
reverse(nums, 0, length)
return nums
>>> rotate([1, 2, 3, 4, 5], 1)
[2, 3, 4, 5, 1]
>>> rotate([1, 2, 3, 4, 5], -1)
[5, 1, 2, 3, 4]
thank you all ! :)
your answers are great and very useful for me.
here is my solution for this question (given that I do these scripts for a basic python course for biologists):
L = input('Enter list of numbers, please: ')
N = input('Enter how many places to rotate: ')
L1 = L[N:]
L2 = L[:N]
L = L1 + L2
print L

I need to generate x random numbers in an interval from 1 to x but each number have to occur only once

I need to generate a random number, actually i need 70128 random numbers form 1 to 70128. Here is what I'm using:
index = numpy.random.randint(1,70128,70128)
The other thing is, that I need each number between 1 and 70128 to be generated only once.
This means that I need a list of 70128 random generated numbers between 1 and 70128 but each number have to occur only once.
You you need x random numbers between 1 and x that are all unique then you just want a shuffled range:
x = 70128
numbers = range(1, x + 1)
random.shuffle(numbers)
If you are using Python 3, you want to add a list() call to the range() result.
Demo on Python 2.7 with x = 10 for practicality:
>>> import random
>>> x = 10
>>> numbers = range(1, x + 1)
>>> random.shuffle(numbers)
>>> numbers
[5, 2, 6, 4, 1, 9, 3, 7, 10, 8]
Use numpy's random.permutation function, which, if given a single scalar argument x, will return a random permutation of the numbers from 0 to x. For instance:
np.random.permutation(10)
Gives:
array([3, 2, 8, 7, 0, 9, 6, 4, 5, 1])
So, in particular, np.random.permutation(70128) + 1 does precisely what you'd like.

Categories

Resources