How to tell if item in list contains certain characters - python

I have a script that creates a list of numbers, and i want to remove all numbers from the list that are not whole numbers (i.e have anything other than zero after the decimal point) however python creates lists where even whole numbers get .0 put on the end, and as a result i cant tell them apart from numbers with anything else. I can't use the int() function as it would apply to all of them and make them all integers, and then i'd lose the ones that originally were.
Here is my code:
z = 300
mylist = []
while(z > 1):
z = z - 1
x = 600851475143 / z
mylist.append(x)
print(mylist)
[y for y in mylist if y #insert rule to tell if it contains .0 here]
the first bit just divides 600851475143 by every number between 300 and 1 in turn. I then need to filter this list to get only the ones that are whole numbers. I have a filter in place, but where the comment is i need a rule that will tell if the particular value in the list has .0
Any way this can be achieved?

You're performing an integer division, so your results will all be integers anyway.
Even if you'd divide by float(z) instead, you'd run the risk of getting rounding errors, so checking for .0 wouldn't be a good idea anyway.
Maybe what you want is
if 600851475143 % z == 0:
mylist.append(600851475143/z)
It's called the "modulo operator", cf. http://docs.python.org/reference/expressions.html#binary-arithmetic-operations
EDIT: Ralph is right, I didn't put the division result into the list. Now it looks ugly, due to the repetition of the division ... :) gnibbler's answer is probably preferable, or Ralph's.

You can use divmod() and only put the result of an "even divide" in to
your list:
z = 300
mylist = []
while(z > 1):
z = z - 1
x,y = divmod(600851475143, z)
if y==0:
mylist.append(x)
print(mylist)

You can use int() - just not the way you were thinking of perhaps
z = 300
mylist = []
while(z > 1):
z = z - 1
x = 600851475143 / z
mylist.append(x)
print(mylist)
[y for y in mylist if y==int(y)]

Use regular expressions to match what you need. In your case, it should be check for ".0" at the end of the string, thus re.search("\.0$", y). Please be aware that you should use re.search, because re.match checks only for match at the beginning of the string.
Edit: sorry, I was disappointed with
however python creates lists where
even whole numbers get .0
and thought that you are making it list of strings. jellybean gave you the answer.

jellybean's answer is quite good, so I'd summarise:
magic_num = 600851475143
filtered_list = [magic_num/i for i in range(300,0,-1) if magic_num%i == 0]
(the division operator should be integer //, but the code coloriser interprets it as a comment, so I've left the single slash)

Related

Why doesn't my if...in statement work in python?

this program takes 3 lists of numbers, and compares A and B to the list n. if a term from A is in n, the happiness increases. if a term from B is in n, the happiness decreases. However, when I am doing these calculations, the if ... in statement to check if a term from A/B is in n doesn't work - I have done print(happy) after each one to check, and I get no result
A = []
B = []
n = []
happy = 0
lengthn, lengthAB = input("").split()
for i in lengthn:
numbers = input("")
newNumbers = numbers.split()
n.append(newNumbers)
for i in lengthAB:
numbers = input("")
ANumbers = numbers.split()
A.append(ANumbers)
for i in lengthAB:
numbers = input("")
BNumbers = numbers.split()
B.append(BNumbers)
long = int(lengthAB)
for i in range(long):
j = int(i)
if A[j - 1] in n:
happy = happy + 1
print(happy)
if B[j - 1] in n:
happy = happy - 1
print(happy)
i = i + 1
print(happy)
Thank you so much for the help!!
You appended a list to n, not each element of that list. You can write
n.extend(newNumbers)
instead.
You could just write n = newNumbers.split(), but as pointed out in a comment, you probably have an indentation error:
for i in lengthn:
numbers = input("")
newNumbers = numbers.split()
n.extend(newNumbers)
Or, you don't need split at all:
for i in lengthn:
number = int(input(""))
n.append(number)
At some point, you probably mean to convert the string inputs to integers; may as well do that immediately after reading the string. (I'm declaring various techniques for handling conversion errors beyond the scope of this answer.)
Contrary to what you seem to expect the variables: lengthn, lengthAB are strings
The for-loop
for i in lengthn:
numbers = input("")
iterates over the characters in the string lengthn. If lengthn='12' it will ask to provide input twice.
If lengthAB is '13' for example you will get 2 numbers in your list BNumbers but later on you try to test 13 values because int('13') is 13.
for i in lengthn:
numbers = input("")
so the numbers you are getting are the form of string it's will iterate on string rather then a number.
You should look for beeter python book. Based on desription I think this should look like this:
def happiness(A, B, n):
return sum(x in n for x in A) - sum(x in n for x in B)
def get_data(prompt=""):
return [int(x) for x in input(prompt).split()]
print(happiness(get_data(), get_data(), get_data()))
https://ideone.com/Q2MZCo

Stacking inline For plus If else

I wrote a line that should sum up all numbers of a string except 0. On a zero it should add 5.
Whats wrong with
s="123450"
o=sum([int(x) for x in s if int(x) != 0 else 5])
it gives syntax error, but
s="123450"
o=sum([int(x) for x in s if int(x) != 0])
works fine.
if at the end of a list comprehension is used as a filter. It can only cause values to be dropped, not replace them with other things. To map values, you have to move the if/else earlier in the comprehension:
o=sum([int(x) if int(x) != 0 else 5 for x in s])
The correct syntax for the first case if -
s="123450"
o=sum([int(x) if int(x) != 0 else 5 for x in s ])
print(o)
OUTPUT :
20
There are many good answers already available on StackOverflow over if-else in list comprehension. Check these -
if else in a list comprehension
List comprehension with if statement
if/else in a list comprehension
More of an aside really (as the general issue of how you are using if inside list comprehensions is well covered in other answers), in this particular case you could do the following:
o = sum(int(x) or 5 for x in s)
This works because or will use the first value if it is "true" (which in the case of integers means non-zero) or the second value if the first is "false" (here, 0).
The other difference here is that I've used a generator expression instead of a list comprehension -- there is no need to build a list just in order to sum the values.

Convert x digit number into two digit number

I am currently having x number in a list, and I am trying to convert inconsistent data that may be in 1 digit, 5 digit or 2 digit.
How can I convert all into 2 digit number?
Example:
def List_Convert_2_Digit(z):
for i in range(len(z)):
while(z[i]<100 or z[i]>10):
if(z[i]<100):
z[i]=z[i]/10
else:
z[i]=z[i]*10
return z
list_a = [5.2,1600,520,3600,13,55,4000]
result_list= List_Convert_2_Digit(list_a)
Result should yields: [52,16,52,36,13,55,40]
But the above code does not work and it's running forever.
I've tried mod, but it is not what I am looking for.
It looks like you just want to take the first two characters from each, and if there is a separator (dot in your case) ignore it.
In that case you can do this:
two_digit_list = [int(str(x).replace('.', '')[:2]) for x in List]
If other non numeric characters than a dot are going to appear your would have to deal with those as well of course :)
What this does is just converts the numbers to a string, removes dots and then grabs the first two characters and converts it back to an int.
EDIT: Since I saw you replied to someone above that single digit numbers should have 0 added to the end you can do this instead to cover that case:
two_digit_list = [int(str(x).replace('.', '')[:2]) if len(str(x).replace('.', '')) > 1 else int(f"{x}0") for x in List]
At that point it's a bit too long to be a pretty list comprehension so you could always just break it up into a for loop if it's unclear, might be a good exercise if nothing else :)
This is a simple solve to this.
yield_list = []
number_list = [5.2,1600,520,3600,13,55,4000]
for number in number_list:
string = str(number)
string =string.replace('.', '')
yield_list.append(string[:2])
yield_list
There is an error in your logic; your < and > are flipped. This code works:
def List_Convert_2_Digit(z):
for i in range(len(z)):
while(z[i]>100 or z[i]<10):
if(z[i]>100):
z[i]=z[i]/10
else:
z[i]=z[i]*10
return z
Solution that increases/decreases the numbers magnitude until we can get the left two digits:
def two_digit_list(lst):
rv = []
for item in lst:
if item < 10:
item *= 10
while item > 99:
item //= 10
rv.append(int(item))
return rv

How to strip white spaces in Python without using a string method?

I am fairly new to programming and have been learning some of the material through HackerRank. However, there is this one objective or challenge that I am currently stuck on. I've tried several things but still cannot figure out what exactly I am doing wrong.
Objective: Read N and output the numbers between 0 and N without any white spaces or using a string method.
N = int(input())
listofnum = []
for i in range(1, N +1):
listofnum.append(i)
print (*(listofnum))
Output :
1 2 3
N = int(input())
answer = ''
for i in range(1, N + 1):
answer += str(i)
print(answer)
This is the closest I can think of to 'not using any string methods', although technically it is using str.__new__/__init__/__add__ in the background or some equivalent. I certainly think it fits the requirements of the question better than using ''.join.
Without using any string method, just using integer division and list to reverse the digits, print them using sys.stdout.write:
import sys
N = int(input())
for i in range(1,N+1):
l=[]
while(i):
l.append(i%10)
i //= 10
for c in reversed(l):
sys.stdout.write(chr(c+48))
Or as tdelaney suggested, an even more hard-code method:
import os,sys,struct
N = int(input())
for i in range(1,N+1):
l=[]
while(i):
l.append(i%10)
i //= 10
for c in reversed(l):
os.write(sys.stdout.fileno(), struct.pack('b', c+48))
All of this is great fun, but the best way, though, would be with a one-liner with a generator comprehension to do that, using str.join() and str construction:
"".join(str(x) for x in range(1,N+1))
Each number is converted into string, and the join operator just concatenates all the digits with empty separator.
You can print numbers inside the loop. Just use end keyword in print:
print(i, end="")
Try ''.join([str(i) for i in range(N)])
One way to accomplish this is to append the numbers to a blank string.
out = ''
for i in range(N):
out += str(i)
print(out)
You can make use of print()'s sep argument to "bind" each number together from a list comprehension:
>>> print(*[el for el in range(0, int(input())+1)], sep="")
10
012345678910
>>>
You have to do a simple math to do this. What they expect to do is multiply each of your list elements by powers of ten and add them up on each other. As an example let's say you have an array;
a = [2,3,5]
and you need to output;
235
Then you multiply each of loop elements starting from right to left by 10^0, 10^1 and 10^2. You this code after you make the string list.
a = map(int,a)
for i in range(len(a)):
sum += (10**i)*a[-i]
print sum
You are done!

program to generate palindromic number

import math
thevalue = 0
for x in range (100,999):
for y in range (100,999):
mynum=x*y
mynum_str=str(mynum)
for z in range(0,math.floor(len(mynum_str)/2)):
if mynum_str[0+z] != mynum_str[len(mynum_str)-1-z]:
break
else:
if (len(mynum_str)-1-z) -1 == z:
thevalue = mynum
print(thevalue)
gives me 580085 which is not the correct answer(suppose to be over 900000)...
Working on http://projecteuler.net/problem=4 ... on tips on where I went wrong?
You don't need an overcomplicated loop to check for the palindromic nature of the number:
# Using extended slice notation to reverse the string
if str(n) == str(n)[::-1]:
print "Palindrome!"
As for a complete solution, your program is just looking for a palindromic number. There's more than one palindromic number that's the product of 3 digits. You want the biggest of those.
(of course, this isn't the complete solution -- but it'd be no fun if we just gave you the solution to a project Euler challenge ;) )
There is an easier way to check for a palindrome. Just reverse your string and compare it to the original: if(mynum_str == mynum_str[::-1])
The reason you get 580085 is that your program only prints out the last value that it finds. (There are 2470 possible palindromes.) Try either storing them in a list and sorting it, or just keeping the max version:
import math
import string
maxpalindrome = 0
for x in range (100,999):
for y in range (100,999):
mynum=x*y
mynum_str=str(mynum)
if(mynum_str == mynum_str[::-1]):
maxpalindrome = max(string.atoi(mynum_str), maxpalindrome)
print(maxpalindrome)

Categories