questions about if,what does 'if +some variable:'(without any condition) mean? - python

def string_to_int_list(s):
L1=[]
for i in s.split(','):
if i:#what does this line mean?
L1.append(int(i))
return L1
I want to convert string to list,and if I delete 'if i',it will remind me that ValueError: invalid literal for int() with base 10: ''

if i has a value, the condition will return true, if the value of i is None (empty), it will return false. It's the same as i != None.
Also I test that if the split function returns an empty string "" it will not pass the if condition.
For check if a string is numeric (0 - 9) you can use str.isdigit()
str.isdigit()
Return true if all characters in the string are digits and there is at least one character, false otherwise.
For 8-bit strings, this method is locale-dependent.
This code works:
def string_to_int_list(s):
L1=[]
for i in s.split(','):
if i and i.isdigit():#what does this line mean?
L1.append(int(i))
return L1
a = "1,2,3,q,43,hello"
b = string_to_int_list(a)
print b
It will return [1, 2, 3, 43]
Note that I remove indentation to return because it has no sense inside the loop.

What you are doing here is splitting your string by , and then converting to integer if you see a valid value.
Let's say your 1,2,3,4,,,5
What the script is returning you a list of [1,2,3,4,5]
You should try what if condition returns for a empty string, None, empty list i.e. [] or {}.
This script will fail if you have "abc,2,3,4,5"
You can also functional loops like
filter(lambda x : x , map(lambda x : int(x) if x else None, a.split(",")))

Related

How to differentiate between a number and a letter or sign?

If I have a digit within a string I can just do:
x = "2"
x.isdigit()
and I get True. But when I do this:
isinstance(x, str)
By my understanding this also results in True.
My question is now how can I tell if it is a character or a number?
Use isalpha() for this:
x = "2"
x.isalpha()
Returns False
The isdigit number checks every character in string and checks if its a digit or not, in other words, can be an number or not, it returns true if every digit is integer.
while the isinstance primarily checks the datatype of the value you pass.
x='2'
isinstance(x,integer)
Since x itself is a string, isinstance(x,str) returns true.
So, to find whether a string contains a number or character, just use x.isdigit(), it will always return true if its a digit otherwise false.

What is the lexicographically smallest string in Python?

What is the lexicographically smallest string in Python? In other words, what is the string x such that x < y is always True (where y is a string)?
For example, in C++ the empty string is the smallest one (see Smallest lexicographical value of a string). Can anyone confirm that the same answer holds for Python?
This is what I've tried so far:
import string
for x in list(string.printable):
assert("" < x)
With x as empty string, x < y for any string y holds True in Python.
We can confirm this:
>>> all('' < x for x in string.printable)
True
all() returns a True if all elements of theĀ iterableĀ are true (or if the iterable is empty). The less than (<) operation of empty string with all string printables is thus a True.
This is true for non-printable characters as well.
The total range vary from 0 to 1,1141,111(0x10FFFF in base 16) (thanks to #AlexHall in comments).
>>> all('' < chr(i) for i in range(0x110000))
True
"" is the smallest string you can get, since its length is 0 (that's also the string returned by str())
However, I did not find anything in the documentation to explicitly confirm that...
https://docs.python.org/3.7/library/stdtypes.html#comparisons
https://docs.python.org/3.7/reference/datamodel.html#object.__lt__

How to check if the string has digits without a try/except or str.isdigit?

NUMBERS = "123456789"
def digit_checker(x):
for t in x:
if t in NUMBERS:
y = True
else:
y = False
return y
sentence = input("Enter a string to check if its all digits: ")
checker = digit_checker(sentence)
print(checker)
As the title states, how would I find if the string has all digits without using the str.isdigit or a try/except. The code keeps checking the first character and not all. How do I fix that?
NUMBERS = "123456789"
def digit_checker(x):
y = True
for t in x:
if t not in NUMBERS:
y = False
return y
You can use all and a generator expression:
NUMBERS = "1234567890"
def digit_checker(x):
return all(t in NUMBERS for t in x)
This will go through each character in x and see if it is in NUMBERS. If not, all will immediately stop checking and return False. Otherwise, it will return True after it has confirmed that every character is a digit. Below is a demonstration:
>>> NUMBERS = "1234567890"
>>> def digit_checker(x):
... return all(t in NUMBERS for t in x)
...
>>> digit_checker('12345')
True
>>> digit_checker('12345a')
False
>>>
Note too that it would be more efficient if you made NUMBERS a set:
NUMBERS = set("1234567890")
That way, t in NUMBERS will perform an O(1) (constant) hash lookup rather than an O(n) (linear) search through the string. Granted, on strings this small, the performance impact of the linear search is not too worrisome. However, that will quickly change whenever you are working with larger strings.
Actually, it looks like it is checking every character, but because it sets y for every character, it is the "numberless" of the last character that determines the value returned, regardless of what the other characters are.
Instead, you should initialize y to True, and only set it to False if you ever find a non-number. In fact, when that happens, you can immediately return.
If you are chefcking for the fact that all the letters are numbers, you can try the following expression:
def digit_checker(x):
return all( t in NUMBERS for t in x )
It is exactly the same as your code except it will also check whether all the characters within x are numbers. This is what has been missing in your code. The return value is always overwritten by the last check. Of course, using a loop and breaking out might be more efficient unless all does that internally for the generator expression, in which case the two are exactly equivalent.
NUMBERS = "1234567890" # Did you miss the 0?
def digit_checker(x):
all_digits = True
for t in x:
if t not in NUMBERS:
all_digits = False
break
return all_digits
A different approach would be to check them as sets:
def digit_checker(x):
return True if set(x).difference(set(NUMBERS)) == set() else False
Perhaps if you clear up the variable names the problem will be more clear:
def digit_checker(sentence):
is_number = True
for character in sentence:
if character in NUMBERS:
is_number = True
else:
is_number = False
return is_number
As you can see, you are evaluating if it is a number for each character, and changing the is_number variable each time. So, only the last character will result in proper evaluation.
You probably want to just return False when a non-digit is first detected. Try if character not in NUMBERS set is_number to False and break the loop.
There are some good answers to do that. Here's another way to do it. You can count the number of characters that are not digits, by storing them in a list, the length of this list should be zero.
NUMBERS = "1234567890"
def digit_checker(x):
return len([t for t in x if t not in NUMBERS]) == 0
print digit_checker('123') #True

If substring in string, when substring has multiple values

I know there is a way to work around it, but I want to understand the underlying logic as to why this doesn't work.
It's a very simple statement, and it only returns as True when the first substring in the "or list" is shown.
for i in list:
if (substring1 or substring2 or substring3) in string:
print(string + " found!")
What am I missing here? I would think the or conditions would equal true if any substring was found in the string. As is, I'm only coming up as true if substring1 is found in string, and no substring2 or substring3.
substring1 or substring2 or substring3
Assuming that substring1 is not the empty string, this expression evaluates to substring1 because substring1 is truthy. This is then checked to see if it's in string. The other substrings have no effect on the statement.
In other words, the ors are evaluated before the in, and the or evaluates to the first truthy value it finds (this is called short-circuiting). You can't use in that way to check whether multiple substrings are in a string.
You want:
substring1 in string or substring2 in string or substring3 in string
Or:
substrings = (substring1, substring2, substring3)
if any(s in string for s in substrings):
>>> string = 'hello'
>>> s1 = 'he'
>>> s2 = 'll'
>>> s3 = 'o'
>>> (s1 or s2 or s3)
'he'
>>> 'he' in string
True
The problem here is that you are first evaluating (s1 or s2 or s3) which will give you s1 if s1 does not evaluate to false. In a boolean context, empty strings evaluate to false:
>>> s1 = ''
>>> (s1 or s2 or s3)
'll'
What you want is s1 in string or s2 in string or s3 in string, this will return true if at least one of the substrings is in the string.
Its because python uses lazy evaluation... for example...
def error():
raise ArithmeticError
print "nothing" or error()
Will Print "nothing" because it evaluates to True in python code does not check error, which would ordinarily raise an error and stop the script from continuing...
print False or error() #raises error and breaks script
(substring1 or substring2 or substring3) #returns the first true value
The correct code should be
for i in list:
if (substring1 in i ) or (substring2 in i) or (substring3 in i):
print(i + " found!")
The above code can find substring when they have multiple values.
(substring1 or substring2 or substring3)
This expression will return the first item in brackets that is not null.
For example, if subtring1 is not null, it will return the value of substring1.
When substring1 is not null,
(substring1 or substring2 or substring3)
equals to
substring1
You probably want any:
if any(substr in string for substr in substrs):
# At least one match

<function>(str1, str2) calling them separately

First off, this IS homework, so I am not expecting any direct answers. I need to take two strings defined by a function (semordnilap(str1, str2)) and I need to see if they are equal when one is reversed. I was wondering if I can call these separately out of the function with semordnilap(str1[0:1) == semordnilap(str2[-1]) I tried this a few ways and I must not be thinking about it correctly, plus of course there is the kicker of trying to do this recursively. Any advise or direction would be helpful.
def semordnilap(str1, str2):
'''
str1: a string
str2: a string
returns: True if str1 and str2 are semordnilap
False otherwise.
'''
if len(str1) != len(str2):
return False
if len(str1) <= 1 or len(str2) <= 1:
return False
if semordnilap(str1[0]) != semordnilap(str2[-1]):
return False
else:
return True
This is what I have so far, getting error of TypeError: semordnilap() takes exactly 2 arguments (1 given)
Given two strings str1 and str2, the easiest way to compare if one is equal to the reverse of the other is by using slicing:
str1 = 'racecar'
str2 = 'racecar'
str1 == str2[::-1]
Out[57]: True
Which is really just checking if str1 is a palindrome (i.e. a reverse of itself).
If you really want to use recursion, you also want to be using slicing: check if str1[0] == str2[-1], and then recursively call your function on str1[1:] and str2[:-1].
The [::-1] syntax is extended slicing syntax, which is valid for strings as well as lists and other sequences.
To reverse a string you use 'this is a string'[::-1].
[::-1] Is slice notation which says include everything from the start to the end of the string but do it in reverse.
'abcdefghijk'[6:1:-2] outputs 'gec' because it goes from the 6th index (starting with 0) up to but not including the first index, in reverse steps of 2.
Read up more on slice notation:Explain Python's slice notation, http://docs.python.org/2.3/whatsnew/section-slices.html
def semordnilap(str1, str2):
if str1 == str2[::-1]: return True
else: return False
One way to do it recursively:
def semordnilap(str1, str2):
if not (len(str1) or len(str2)): return True
if not (len(str1) and len(str2)): return False
if str1[0] != str2[-1]: return False
return semordnilap(str1[1:], str2[:-1])
The first line checks if both strings are empty (0 evaluates to False, any other number is True). len(str1) returns the length as an integer.
Then it checks if only one of the strings is empty in which case they are not equal.
Then it checks if the first letter is the same as the last letter.
Then it repeats the process with the each string (minus the first letter of str1 and minus the last letter of str2). It goes until one of the base cases is reached. The base case is what is returned. So it will only return True when then first letter was equal to the last letter each round until both strings ran out of characters at the same time.

Categories

Resources