This question already has answers here:
How do I compare version numbers in Python?
(16 answers)
Closed 6 years ago.
I want to get the maximum value from a list.
List = ['1.23','1.8.1.1']
print max(List)
If I print this I'm getting 1.8.1.1 instead of 1.23.
What I am doing wrong?
The easiest way is, to use tuple comparison.
Say:
versions = ['1.23','1.8.1.1']
def getVersionTuple(v):
return tuple(map(int, v.strip().split('.')))
Now you can use, print(max(map(getVersionTuple, versions))) to get the maximum.
EDIT:
You can use '.'.join(map(str, m)) to get the original string (given m holds the max tuple).
These aren't numbers, they are strings, and as such they are sorted lexicographically. Since the character 8 comes after 2, 1.8.1.1 is returned as the maximum.
One way to solve this is to write your own comparing function which takes each part of the string as an int and compares them numerically:
def version_compare(a, b):
a_parts = a.split('.')
b_parts = b.split('.')
a_len = len(a_parts)
b_len = len(b_parts)
length = min(a_len, b_len)
# Compare the parts one by one
for i in range(length):
a_int = int(a_parts[i])
b_int = int(b_parts[i])
# And return on the first nonequl part
if a_int != b_int:
return a_int - b_int
# If we got here, the longest list is the "biggest"
return a_len - b_len
print sorted(['1.23','1.8.1.1'], cmp=version_compare, reverse=True)[0]
A similar approach - assuming these strings are version numbers - is to turn the version string to an integer list:
vsn_list=['1.23', '1.8.1.1']
print sorted( [ [int(v) for v in x.split(".")] for x in vsn_list ] )
When you compare strings, they are compared character by character so any string starting with '2' will sort before a string starting with '8' for example.
Related
This question already has answers here:
String count with overlapping occurrences [closed]
(25 answers)
Closed last year.
C = 'Kabansososkabansosos'
I need the number of times the string 'sos' occurs in C. I've already used the C.count('sos') method, but it did not help me.
def count_occurrences(expression,word):
L = len(word)
counts = 0
for i in range(L,len(expression)+1):
if expression[i-L:i]==word:
counts += 1
return counts
count_occurrences('Kabansososkabansosos','sos')
>>> 4
To be explicit, your problem is that you want to count non-overlapping occurrences of the sub-string, which is not what str.count() does.
First, let's use the powerful re (regular expression) module instead of str.count():
C = 'Kabansososkabansosos'
matches = re.findall(r'sos', C)
n = len(matches)
print(n) # 2
At first sight this seems silly, as it 1) also does not work with over-lapping occurrences and 2) produce a (potential) large list of matches, all of which will just be the str 'sos'.
However, using the clever trick of the accepted answer here, we can make re.findall() work with overlapping occurrences:
C = 'Kabansososkabansosos'
matches = re.findall(r'(?=(sos))', C)
n = len(matches)
print(n) # 4
If C is very large, we would like to avoid the potentially large temporary list matches. We can do this by instead using the re.finditer() function, which returns a generator rather than the list:
C = 'Kabansososkabansosos'
matches = re.finditer(r'(?=(sos))', C)
n = sum(1 for match in matches)
print(n) # 4
where the sum() over 1s simply produce the length of the iterator, i.e. the number of matches.
This question already has answers here:
Code to output the first repeated character in given string?
(10 answers)
Closed 2 years ago.
You are given a string S
Your task is to find the first occurrence of an alphanumeric character in S(read from left to right) that has consecutive repetitions.
Input Format
A single line of input containing the string S.
Output Format
Print the first occurrence of the repeating character. If there are no repeating characters, print -1.
For example,
If I input the below string
..12345678910111213141516171820212223
the result is
1
I solved this problem but that's not correct.
My code is
def firstRepeatedChar(str):
h = {}
for ch in str:
if ch in h:
return ch;
else:
h[ch] = 0
return -1
n = input()
print(firstRepeatedChar(n))
but if I input the ^^cmmit^^, the result is not correct.
How can I solve this problem with python? Please help me.
A pythonic way to do something like this is to use zip() to make consecutive pairs of tuples (like (1, 2), (2, 3) ... and then just return the first one where both are equal and alphanumeric.
next() takes an optional parameter for what to return when there's nothing left, to which here you can pass -1. isalnum() can be used to test is a string is alphanumeric:
def firstRepeatedChar(s):
return next((j for j, i in zip(s, s[1:]) if j == i and j.isalnum()), -1)
firstRepeatedChar("..12345678910111213141516171820212223")
# 1
firstRepeatedChar("^^cmmit^^")
# 'm'
firstRepeatedChar("^^cmit^^")
# -1
This question already has answers here:
How can I find all common letters in a set of strings?
(2 answers)
Closed 8 years ago.
I need to make a function that takes two string arguments and returns a string with only the characters that are in both of the argument strings. There should be no duplicate characters in the return value.
this is what I have but I need to make it print things only once if there is more then one
def letter(x,z):
for i in x:
for f in z:
if i == f:
s = str(i)
print(s)
If the order is not important, you can take the intersection & of the set of characters in each word, then join that set into a single string and return it.
def makeString(a, b):
return ''.join(set(a) & set(b))
>>> makeString('sentence', 'santa')
'nts'
Try this
s = set()
def letter(x,z):
for i in x:
for f in z:
if i == f:
s.add(i)
letter("hello","world")
print("".join(s))
It will print 'ol'
If sets aren't your bag for some reason (perhaps you want to maintain the order in one or other of the strings, try:
def common_letters(s1, s2):
unique_letters = []
for letter in s1:
if letter in s2 and letter not in unique_letters:
unique_letters.append(letter)
return ''.join(unique_letters)
print(common_letters('spam', 'arthuprs'))
(Assuming Python 3 for the print()).
I learning Python and during solution an exercise, function filter() returns empty list and i can't understand why. Here is my source code:
"""
Using the higher order function filter(), define a function filter_long_words()
that takes a list of words and an integer n and returns
the list of words that are longer than n.
"""
def filter_long_words(input_list, n):
print 'n = ', n
lengths = map(len, input_list)
print 'lengths = ', lengths
dictionary = dict(zip(lengths, input_list))
filtered_lengths = filter(lambda x: x > n, lengths) #i think error is here
print 'filtered_lengths = ', filtered_lengths
print 'dict = ',dictionary
result = [dictionary[i] for i in filtered_lengths]
return result
input_string = raw_input("Enter a list of words\n")
input_list = []
input_list = input_string.split(' ')
n = raw_input("Display words, that longer than...\n")
print filter_long_words(input_list, n)
Your function filter_long_words works fine, but the error stems from the fact that when you do:
n = raw_input("Display words, that longer than...\n")
print filter_long_words(input_list, n)
n is a string, not an integer.
Unfortunately, a string is always "greater" than an integer in Python (but you shouldn't compare them anyway!):
>>> 2 > '0'
False
If you're curious why, this question has the answer: How does Python compare string and int?
Regarding the rest of your code, you should not create a dictionary that maps the lengths of the strings to the strings themselves.
What happens when you have two strings of equal length? You should map the other way around: strings to their length.
But better yet: you don't even need to create a dictionary:
filtered_words = filter(lambda: len(word) > n, words)
n is a string. Convert it to an int before using it:
n = int(raw_input("Display words, that longer than...\n"))
Python 2.x will attempt to produce a consistent-but-arbitrary ordering for objects with no meaningful ordering relationship to make sorting easier. This was deemed a mistake and changed in the backwards-incompatible 3.x releases; in 3.x, this would have raised a TypeError.
I don't know what your function does, or what you think it does, just looking at it gives me a headache.
Here's a correct answer to your exercise:
def filter_long_words(input_list, n):
return filter(lambda s: len(s) > n, input_list)
My answer:
def filter_long_words():
a = raw_input("Please give a list of word's and a number: ").split()
print "You word's without your Number...", filter(lambda x: x != a, a)[:-1]
filter_long_words()
This question already has answers here:
Removing elements that have consecutive duplicates
(9 answers)
Closed 3 years ago.
For a string such as '12233322155552', by removing the duplicates, I can get '1235'.
But what I want to keep is '1232152', only removing the consecutive duplicates.
import re
# Only repeated numbers
answer = re.sub(r'(\d)\1+', r'\1', '12233322155552')
# Any repeated character
answer = re.sub(r'(.)\1+', r'\1', '12233322155552')
You can use itertools, here is the one liner
>>> s = '12233322155552'
>>> ''.join(i for i, _ in itertools.groupby(s))
'1232152'
Microsoft / Amazon job interview type of question:
This is the pseudocode, the actual code is left as exercise.
for each char in the string do:
if the current char is equal to the next char:
delete next char
else
continue
return string
As a more high level, try (not actually the implementation):
for s in string:
if s == s+1: ## check until the end of the string
delete s+1
Hint: the itertools module is super-useful. One function in particular, itertools.groupby, might come in really handy here:
itertools.groupby(iterable[, key])
Make an iterator that returns consecutive keys and groups from
the iterable. The key is a function computing a key value for each
element. If not specified or is None, key defaults to an identity
function and returns the element unchanged. Generally, the iterable
needs to already be sorted on the same key function.
So since strings are iterable, what you could do is:
use groupby to collect neighbouring elements
extract the keys from the iterator returned by groupby
join the keys together
which can all be done in one clean line..
First of all, you can't remove anything from a string in Python (google "Python immutable string" if this is not clear).
M first approach would be:
foo = '12233322155552'
bar = ''
for chr in foo:
if bar == '' or chr != bar[len(bar)-1]:
bar += chr
or, using the itertools hint from above:
''.join([ k[0] for k in groupby(a) ])
+1 for groupby. Off the cuff, something like:
from itertools import groupby
def remove_dupes(arg):
# create generator of distinct characters, ignore grouper objects
unique = (i[0] for i in groupby(arg))
return ''.join(unique)
Cooks for me in Python 2.7.2
number = '12233322155552'
temp_list = []
for item in number:
if len(temp_list) == 0:
temp_list.append(item)
elif len(temp_list) > 0:
if temp_list[-1] != item:
temp_list.append(item)
print(''.join(temp_list))
This would be a way:
def fix(a):
list = []
for element in a:
# fill the list if the list is empty
if len(list) == 0:list.append(element)
# check with the last element of the list
if list[-1] != element: list.append(element)
print(''.join(list))
a= 'GGGGiiiiniiiGinnaaaaaProtijayi'
fix(a)
# output => GiniGinaProtijayi
t = '12233322155552'
for i in t:
dup = i+i
t = re.sub(dup, i, t)
You can get final output as 1232152