我需要定义一个接收字符串(可能包含数字,字母和/或特殊符号)的函数,并返回一个包含平均值的浮点数,考虑字符串中最后一个位置开始的字符串中的所有数字,考虑所有数字(向后)直到找到一个字母或直到到达字符串的开头(如果它是一个数字,则包括字符串中的第一个字符用于计算)。如果字符串中没有数字,或者在找到第一个数字之前找到了一个字母,那么该函数应返回值0.0。
例如,avgBackw(“ - 1 --- 2 - A - 3--4--”)应该返回3.5,因为4和3的平均值是3.5。
As an example, the following code fragment:
value = avgBackw("-1---2--A--3--4--")
print(value)
should produce the output:
3.5
这是我到目前为止最远的...我不知道从哪里开始..
def avgBackw(lst):
rv = []
for n in lst[::-1]:
try:
rv.append(int(lst))
except:
return len(rv)
return len(rv)
答案 0 :(得分:0)
使用isalpha()
和isdigit()
def avgBack(string):
sum, count = 0.0, 0
for s in string[::-1]:
if s.isalpha():
break
if s.isdigit():
sum += int(s)
count+=1
return float(sum/count) if count else 0
答案 1 :(得分:0)
您需要做的是:
1。删除除数字和字母之外的所有字符
2。反转已剥离的列表
3. 检查基本情况
4. 计算找到字符前所有数字的平均值
这是一种蛮力方法(没有有用的库函数):
def average_back(string):
# sum count for average
count = 0
sums = 0.0
# strip the string except for the digits and letters
stripped = []
for char in string:
if char.isdigit() or char.isalpha():
stripped.append(char)
# reverse the string
reverse = stripped[::-1]
# if list is empty, of no digits are found, or the first letter is a letter
if not reverse or not has_number(reverse) or reverse[0].isalpha():
return sums
# loop until character is found
for char in reverse:
if char.isalpha():
break
else:
sums += float(char)
count += 1
# return average
return sums / count
def has_number(string):
for char in string:
if (char.isdigit()):
return True
return False
使用更高阶函数的另一个更简洁(可以改进)的实现,例如map()
,any()
,itertools.takewhile()
和str.join()
:
from itertools import takewhile
def average_back2(string):
# strip the string except for the digits and letters
stripped = "".join(x for x in string if x.isalpha() or x.isdigit())
# reverse the string
reverse = stripped[::-1]
# if list is empty, of no digits are found, or the first letter is a letter
if not reverse or not any(x.isdigit() for x in reverse) or reverse[0].isalpha():
return 0.0
# concatenate numbers until non-digit is found
valid_numbers = "".join(takewhile(lambda x : not x.isalpha(), reverse))
# convert string to list of integers
numbers = list(map(int, valid_numbers))
# return sum
return sum(numbers) / len(numbers)
其工作原理如下:
>>> average_back("-1---2--A--3--4--")
3.5
>>> average_back2("-1---2--A--3--4--")
3.5
>>> average_back("-1---2--A--3--A--")
0.0
>>> average_back2("-1---2--A--3--A--")
0.0
>>> average_back("-A---A--A--A--1--")
1.0
>>> average_back2("-A---A--A--A--1--")
1.0
>>> average_back("-A---A--A--A--A--")
0.0
>>> average_back2("-A---A--A--A--A--")
0.0
>>> average_back("-5---4--3--2--1--")
3.0
>>> average_back2("-5---4--3--2--1--")
3.0
>>> average_back("-A---4--3--2--1--")
2.5
>>> average_back2("-A---4--3--2--1--")
2.5
>>> average_back("-A---4--A--2--1--")
1.5
>>> average_back2("-A---4--A--2--1--")
答案 2 :(得分:0)
您可以使用regex
来解决您的问题,如下例所示:(请参阅评论以了解引人注目的内容):
import re
def find_sep(a):
'''Find the separator which is anything except numbers and "-" '''
# é, è, æ, etc ... are not a valid separators.
# Otherwise, add them to the next line in the regex rule
sep = re.findall(r'[a-zA-Z]', a[::-1])
if sep:
# Reverse the string
# And take the first part of the string if we find a separator
return a[::-1].split(sep[0])[0]
else:
# Return the string reversed
return a[::-1]
def average_backwards(a):
'''Reverse the string and calculate the average'''
# Find the seperator if exists and return an inversed string with numbers if they exists
b = find_sep(a)
# Find all the numbers
nums = re.findall(r'(\d+)', b[::-1])
if nums:
avg = round(sum(map(int, nums))/len(nums), 2)
return avg
return 0.0
# Test
nums = ["-1---2--b--3--04--", "-1---2--e--3--4--", "-1---2--A--3--A--", "-1---2--A--3----",
"-A---A--A--A--1--", "-A---A--A--+--1--", "-A---A--A--A--A--", "-A---2--A--A--A--",
"-5---4--3--2--1--", "-5-Z--4--3--2--1--", "-A---4--3------", "-A---4--c--2--1--",
"----4--A--2--1--", "-A---4--A--2--1--", "-5-Z--4-+3--2--1-"]
for num in nums:
print('{0} -> avg: {1}'.format(num, average_backwards(num)))
输出:
-1---2--b--3--04-- => 3.5
-1---2--e--3--4-- => 3.5
-1---2--A--3--A-- => 0.0
-1---2--A--3---- => 3.0
-A---A--A--A--1-- => 1.0
-A---A--A--+--1-- => 1.0
-A---A--A--A--A-- => 0.0
-A---2--A--A--A-- => 0.0
-5---4--3--2--1-- => 3.0
-5-Z--4--3--2--1-- => 2.5
-A---4--3------ => 3.5
-A---4--c--2--1-- => 1.5
----4--A--2--1-- => 1.5
-A---4--A--2--1-- => 1.5
-5-Z--4-+3--2--1- => 2.5
答案 3 :(得分:0)
我永远不会错过在一个问题上抛出itertools.groupby的机会:
from itertools import groupby
def avgBackw(string):
digits = list()
for key, group in groupby(string[::-1], lambda c: c.isalnum() + c.isdigit()):
if key == 1: # we hit one or more letters
break
if key == 2: # we hit one or more digits
digits += group
return sum(map(int, digits)) / len(digits) if digits else 0