Python:从文本中拆分数字,然后对它们求和



我有一个格式如下的文本文件,我将其引入Python:

    hammer#9.95
    saw#20.15
    shovel#35.40

最终,我想开发一个动态查询,允许我删除"#"符号并替换为"$"符号,然后将文本文件中的值相加/计算其中的项目数。我通过一些试验和错误提出了这个,但它不是动态的处理文本文件中的更改:

 # display header line for items list
print('{0: <10}'.format('Item'), '{0: >17}'.format('Cost'), sep = '' )
# add your remaining code below
with open('invoice.txt','rt') as infile:
    for line in infile:
        print("{:<21} {}".format(line.strip().split('#')[0],"$"+line.strip().split("#")[1]))
print(' ')
str1 = 'Total costt' +'      ' + '$65.50'
print(str1)
str2 = 'Number of toolst' + '           ' +'3'
print(str2)

有什么建议吗?提前感谢您的阅读。

您可以通过以下方式执行此操作:

d = ['hammer#9.95', 'saw#20.15', 'shovel#35.40']
## replace hash
values = []
items = set()
for line in d:
    line = line.replace('#', '$')
    values.append(line.split('$')[1])
    items.add(line.split('$')[0])
## sum values
sum(map(lambda x: float(x), values)) 
65.5
## count items
len(items)
3

解释:

  1. 为了对项目进行计数,我们使用了一个集合来获取唯一计数。如果您想要全部,请改用列表。
  2. 我们通过在美元符号上拆分从列表中提取数字来计算总和。
prices = []
with open(...) as infile:
    for line in infile.readlines()
        price = line.split('#')[-1]
        prices.append(float(price))
result = sum(prices)

怎么样:

items = {}
with open("temp.txt") as f:
    for line in f:
        item,cost = line.split('#')
        cost = float(cost)
        items[item] = cost

现在,您有一个字典,按项目"name"键控(因此它们在您的文件中必须是唯一的,否则字典不是这里最好的结构(,每个值都是与解析成本对应的浮点数。

# Print items and cost
print(items.items())
#> dict_items([('hammer', 9.95), ('saw', 20.15), ('shovel', 35.4)])
# Print Number of Items
print(len(items))
#> 3
# Print Total Cost (unformatted)
print(sum(items.values()))
#> 65.5
# Print Total Cost (formatted)
print("$%.02f" % sum(items.values()))
#> $65.50

您可能需要查看一些极端情况,以使此解决方案更加可靠。 例如,如果项目"name"包含一个#符号(即每行有多个#(,则值的格式不正确,无法通过float等进行解析。

您可以使用:

total_price, total_products = 0, 0
for line in [open('invoice.txt').read().split("n")]: 
    total_price += float(line.split("#")[1]); total_products += 1
print("Total Pricen${}".format(total_price))
print("Number of toolsn{}".format(total_products))

Total Price
$65.5
Number of tools
3

我们必须将价格(line.split("#")[1](cast,这是一个string,到一个float,否则当我们试图将其addtotal_price时,我们会得到一个Type Error

float(line.split("#")[1])

由于我早就应该更新我的 Python 技能,我对你的问题有一些乐趣,并想出了一个解析器类:

import re
from contextlib import contextmanager

class Parser(object):
    def __init__(self, file_path, regex):
        self.file_path = file_path
        self.pattern = re.compile(regex, flags=re.LOCALE | re.IGNORECASE | re.UNICODE)
        self.values = []
        self.parse()
    @contextmanager
    def read_lines(self):
        try:
            with open(self.file_path, "r", encoding="utf-8") as f:
                yield f.readlines()
        except FileNotFoundError:
            print("Couldn't open file: ", self.file_path)
    def parse_line(self, line):
        try:
            return self.pattern.match(line).groupdict()
        except AttributeError:
            return None
    def parse(self):
        with self.read_lines() as lines:
            self.values = [value for value in map(self.parse_line, lines) if value]
    def get_values(self, converters=dict()):
        if len(converters) is 0:
            return self.values
        new_values = []
        for value in self.values:
            new_value = {}
            for key in value:
                if key in converters:
                    new_value[key] = converters[key](value[key])
                else:
                    new_value[key] = value[key]
            new_values.append(new_value)
        return new_values

此类采用文件路径和类似正则表达式的字符串,然后将其编译为正则表达式对象。在实例化时,它会读取和解析文件的内容,同时忽略无效行(与空行等正则表达式语法不匹配(。

我还添加了一个 get_values 方法,该方法可以将转换器应用于正则表达式中的命名组,请参阅示例(它将每行的命名组price转换为浮点值(:

parser = Parser(r"fully_qualified_file_path.txt", r".s*(?P<name>[ws]+)#(?P<price>[d.]+)")
total = 0
count = 0
for line in parser.get_values({'price': lambda x: float(x)}):
    total += line['price']
    count += 1
    print('Item: {name}, Price: ${price}'.format(**line))
print()
print('Item count:', count)
print('Total:', "${0}".format(total))

结果

Item: hammer, Price: $9.95
Item: saw, Price: $20.15
Item: shovel, Price: $35.4
Item count: 3
Total: $65.5

但撇开编码的乐趣不谈,我建议你尝试获取干净的类似csv的数据,并通过csv类正确处理它。

最新更新