def is_balanced(input_str):
s = list()
for ch in input_str:
if ch == '(':
s.append(ch)
if ch == ')':
if not s:
return False
s.pop()
return not s
Can anyone explain what is really happening after the line "if ch == ')':" ?
if not s:
checks whether the list is empty or not, if the list is empty then the condition inside is executed.
let's say you provide ())()() in input, so for:
-> the 0th index it will first add ( into s
-> for 1st index (i.e )): it will first check if s is empty or not, as here we have ( in s so the if condition will not execute, then it goes on to pop the value from the list. (notice now the list is empty)
-> on coming to the 2nd index (i.e )): it will first check if the list is empty or not, as the list is empty it will return False
Related
Very new to any kind of coding. I would like to write a function that will return the elements of a numeric list, up to the first even number. For example, if the list is [1,5,7,8,9] it will return [1,5,7]
I know the below is not correct, but I am having trouble passing the list into the while loop.
def iter_up_to_even(num_lst):
i=0
new_lst=[]
while i < len(num_lst):
if i%2!=0:
new_lst.append(num_lst)
i=i+1
if i %2==0:
break
return new_lst
Looks like you might have some indentation issues. Try this solution:
def iter_up_to_even(num_list):
to_return = []
current_index = 0 if len(num_list) > 0 else len(num_list)
while current_index < len(num_list):
if num_list[current_index] % 2 == 1:
to_return.append(num_list[current_index])
else:
break
current_index += 1
return to_return
Explanation
We start with an empty list to_return, which we will return at the end of our function. Next, we iterate through each item in the input list num_list. If the input list num_list is empty to begin with, we don't even enter the while loop (see Line 3). If the item is odd, we append it to our to_return list. If it's even, we break from our loop and return to_return.
In addition, you should compare values in the list (e.g. num_list[i]), rather than the current index in the list (e.g. i).
I am trying to build a function which returns the most occurred character in a given string and it's working pretty nicely, but how do I return None if the characters have same frequency?
Like for input: 'abac'
Expected output is: 'a'
and for input: 'abab'
Expected output is: None
I have tried using a dictionary to store character frequency and then returning the element with largest value.
def most_occuring_char(str1):
count = {}
max = 0
c = ''
for char in str1:
if char in count.keys():
count[char]+=1
else:
count[char] = 1
for char in str1:
if max < count[char]:
max = count[char]
c = char
return c
I don't know how to check whether the count dictionary elements have same frequency.
You can do that counting with the dict using collections.Counter.
You basically only have to add a check to see if the maximum count is unique (if so, return the char with maximum number of occurrences) or not (if so, return None):
from collections import Counter
def most_occurring_char(string):
counter = Counter(string)
max_char_count = max(counter.values())
is_unique = len([char_count for char_count in counter.values() if char_count == max_char_count]) == 1
if is_unique:
char = [char for char, count in counter.items() if count == max_char_count][0]
return char
return None
# Tests
assert most_occurring_char('abac') == 'a'
assert most_occurring_char('abab') is None
Once you have a dictionary containing the counts of every character (after your first for loop), you can inspect this to determine whether certain counts are the same or not.
If you wish to return None only when all the character counts are the same, you could extract the values (i.e. the character counts) from your dictionary, sort them so they are in numerical order, and compare the first and last values. Since they are sorted, if the first and last values are the same, so are all the intervening values. This can be done using the following code:
count_values = sorted(count.values())
if count_values[0] == count_values[-1]: return None
If you wish to return None whenever there is no single most frequent character, you could instead compare the last value of the sorted list to the second last. If these are equal, there are two or more characters that occur most frequently. The code for this is very similar to the code above.
count_values = sorted(count.values())
if count_values[-1] == count_values[-2]: return None
Another possibility:
def most_occuring_char(s):
from collections import Counter
d = Counter(s)
k = sorted(d, key=lambda x:d[x], reverse=True)
if len(k) == 1: return k[0]
return None if len(k) == 0 or d[k[0]] == d[k[1]] else k[0]
#Test
print(most_occuring_char('abac')) #a
print(most_occuring_char('abab')) #None (same frequencies)
print(most_occuring_char('x')) #x
print(most_occuring_char('abcccba')) #c
print(most_occuring_char('')) #None (empty string)
I want to know if the code I wrote can be shortened further, I was practicing and I came up to a task which asks you to return a boolean value, this is what the question says:
Given two strings, return True if either of the strings appears at the
very end of the other string, ignoring upper/lower case differences
(in other words, the computation should not be "case sensitive").
Note: s.lower() returns the lowercase version of a string.
def end_other(a, b):
x = len(b)
n = a[-x:]
y = len(a)
m = b[-y:]
if b.lower() == n.lower() or a.lower() == m.lower() :
return True
else:
return False
The Code is working properly but I wondered if it can be shortened more so it looks good.
You can write it like this:
def end_other(a, b):
n = a[-len(b):]
m = b[-len(a):]
return b.lower() == n.lower() or a.lower == m.lower()
I removed variables x and y because they are used just one time and then I also remove the if-else statement because it's unnecessary, in fact you can just return the result of the comparison instead of checking it's result and returning it a second time.
I managed to find this code online which showed me how to find and print a repeated character in a string. I'm confused as to how it's working though. I don't understand what the h[i] = 0 part is technically doing. Can someone please explain?
a = 'abcdeab'
h = {}
for i in a:
if i in h:
print(i)
else:
h[i] = 0
I understand how it's iterating over the string, but I don't understand how it's being added to the dictionary in order to be checked if it already exists in that dictionary or not. Setting h[i] = 0 is what's throwing me off. I don't understand why it's being set to 0.
I'm adding this after the problem was answered:
I ended up creating a different solution and thought I would post it in case anyone else was looking into the same problem. It is as follows (using a list instead of a dictionary):
a = 'abcdeab'
h = []
for i in a:
if i in h:
print(i)
else:
h.append(i)
Also, if you're looking for ONLY the first occurrence of a repeated character, you would add break after print(i). In this case, it would only print a instead of both a and b.
The variable h has been defined to be a dictionary. For each letter in your input string, if it be present in the map, it gets printed, otherwise the map gets assigned a (key, value) pair of (letter, 0). That is, an entry is made into the map with the letter as the key, and zero as the (arbitrary) value. Here is your loop with some comments:
for i in a:
if i in h: # if the key 'i' exists in the dictionary
print(i)
else:
h[i] = 0 # otherwise add an entry for this letter
I am trying to write a code which prints True if given string has at max 2 consecutive c, and at max 1 b. I am using recursion to reduce the string and check that at max 'c' is present in the same index twice.But my recursion is not stopping till it empties the whole list. Can you please suggest what's wrong with my code. Thanks!
def stringcond(N,count=0,k=0):
N=list(N)
if(N.count('b')>1):
return False
if len(N)<2:
return True
else:
for i,j in enumerate(N):
if(j=='c'):
del N[i]
count+=1
if(k==i and count>2):
return False
stringcond(N,count=count,k=i)
return True
You have several mistakes. First, why are you splitting the characters into a list? There is a perfectly good count method for strings.
Your recursion fails because you ignore the return value. You would want something like
if not stringcond(N,count=count,k=i):
return False
# I make no claim that this logic is correct.
In any case, there is no need to recur. Use count to check the quantity of "b" and many-'c' substrings:
def stringcond(s, c_max=0):
return s.count('b') <= 1 and \
s.count("c" * (c_max+1)) == 0
You have to use the result of the stringcond call. Now your function will only return whatever was determined on the top level call.