如何使用同一文件中其他位置包含的数据替换文件中的行?

时间:2015-09-14 19:57:36

标签: python algorithm io

我们说我有一个名为' Food'列出一些食物的名称及其价格。这些物品中的一些是原料,而其他物品是由不同数量的这些物质制成的 - 例如我可以手动将鸡蛋的价格列为1,并发现煎蛋的默认价格为10,但后来发现只有煎蛋卷需要5个鸡蛋,所以我需要程序来读取鸡蛋的价格,找到包含煎蛋卷的行,并用" omelette代替它:" + str(5 *个鸡蛋)。我可能还需要添加额外的成分/食物,例如一堆由5个煎蛋卷制成的煎蛋卷。基本目标是可以只编辑鸡蛋的价值,以及更新煎蛋卷和鸡蛋托盘的价值。我只是通过创建文件中包含的行列表来启动代码。

with open("Food.txt") as g:
    foodlist=g.readlines()

文件' Food.txt'将采用以下格式:

eggs: 5
omelette: 20
pileofomelettes: 120

...等 并且在代码运行后它应该看起来像

eggs: 5
omelette: 25
pileofomelettes: 125

我会手动编码关系,因为它们不太可能改变(即使他们这样做,我也很容易进入并改变系数)

将被python以列表格式读取,如

' ['鸡蛋2 \ n','面粉1 \ n','黄油1 \ n','糖3 \ n','杏仁5 \ n','樱桃8 \ n']'

我搜索了搜索/替换算法,可以搜索特定的短语并将其替换为另一个特定的短语,但我不知道如果该行可能会发生变化,我将如何应用它(如果用户想要更新与其相关的所有值,则用户可以更改原始成分值。我能想到的一个解决方案是将它们转换为字典格式,将它们全部列为字符串整数值对,这样我就可以根据存储在其他字符串 - 整数对中的整数值替换该对的整数部分但是,由于缺乏经验,我不知道如何将列表(或原始文件本身,甚至更好)转换为字典。

非常感谢任何有关如何执行此计划步骤的建议:)

编辑 - 在程序的实际应用中,最终文件中列出项目的顺序并不重要,因此如果我列出了1个地方的所有原料和所有复合项目在另一个(如果需要添加更多的原始项目,它们之间有大的空间)那么我可以以任意顺序重写整个文件的后半部分而没有问题 - 只要原始的行位置成分保持不变。

3 个答案:

答案 0 :(得分:0)

您的程序如何知道每个项目的组件?我建议您保留两个文件:一个是原子项目(鸡蛋),另一个是食谱(煎蛋< = 5个鸡蛋)。

阅读这两个文件。存储原子成本,记住您拥有的这些项目中有多少 atomic_count 。从配方文件中扩展此表,一次一行。如果您正在阅读的食谱完全由已知成本的项目组成,则计算成本并将该项目添加到“已知”列表中。否则,将配方附加到“稍后”列表并继续。

当您到达两个输入文件的末尾时,您将获得已知成本的列表,以及一些依赖于配方文件中较远项目的其他配方。现在循环通过这个“未知”列表,直到(a)它为空; (b)你没有任何已知成分的东西。如果情况(b),您的输入有问题:无定义的成分或循环依赖。打印剩余的配方列表并调试输入文件。

如果是(a),您现在可以打印Food.txt列表了。浏览“已知”列表,一次写出一个项目或食谱。当你到达item [atomic_count]时,写出第二个文件,一个新的食谱列表。这是您的旧配方列表,但是以自上而下的有用顺序排列。将来,在第一次通过后,您将不会有任何“未知”的食谱。

对于未来的变化......不要打扰。您只有173个项目,并且列表听起来不可能超过500.当您更改或添加项目时,只需手动编辑该文件并重新运行该程序。这将比您尝试编写的字符串替换算法更快。

总之,我建议你只做初始计算问题,这比添加字符串更新要简单得多。不要进行增量更新;从头开始重做整个列表。对于如此小的列表,计算机将比编写和调试额外编码更快地完成此任务。

答案 1 :(得分:0)

我仍然不确定你在问什么,但这就是我想出来的......

from collections import OrderedDict

food_map = {'omelette': {'eggs': 5, 'price': None}, 'pileofomelettes': {'eggs': 25, 'price': None}, 'eggs': {'price': 5}}

with open('food.txt', 'rb') as f:
    data = f.read().splitlines()

data = OrderedDict([(x[0], int(x[1])) for x in [x.split(': ') for x in data]])

for key, val in data.items():
    if key == 'eggs':
        continue
    food_rel = food_map.get(key, {})
    val = food_rel.get('eggs', 1) * food_map.get('eggs', {}).get('price', 1)
    data[key] = val

with open('out.txt', 'wb') as f:
    data = '\n'.join(['{0}: {1}'.format(key, val) for key, val in data.items()])
    f.write(data)

答案 2 :(得分:0)

好的,我建议创建一个关系文本文件,如果您认为关系可以稍后更改,或者只是为了使您的代码更易于阅读和更改,您可以解析它。然后可以对其进行解析以找到原料和配合物之间所需的关系。设为“relations.txt”,类型为:

omelette: 5 x eggs + 1 x onions
pileofomelettes: 6 x omelette

在这里,您可以输入任意数量的成分:

  

复杂:number1 x ingredient1 + number2 x ingredient2 + ...

等等。 而你的food.txt包含所有成分和配合物的价格:

eggs: 2
onions: 1
omelette: 11.0
pileofomelettes: 60

现在我们可以看到有意未在此处正确映射pileofomlettes的值。因此,我们将运行下面的代码,您也可以更改数字并查看结果。

#!/usr/bin/python
''' This program takes in a relations file and a food text files as inputs
and can be used to update the food text file based on changes in either of these'''

relations = {}
foodDict = {}

# Mapping ingredients to each other in the relations dictionary
with open("relations.txt") as r:
    relationlist=r.read().splitlines()
    for relation in relationlist:
        item, equatedTo = relation.split(': ')
        ingredientsAndCoefficients = equatedTo.split(' + ')
        listIngredients = []
        for ingredient in ingredientsAndCoefficients:
            coefficient, item2 = ingredient.split(' x ')
            # A list of sets of amount and type of ingredient
            listIngredients.append((float(coefficient),item2))
        relations.update({item:listIngredients})


# Creating a food dictionary with values from food.txt and mapping to the relations dictionary
with open("food.txt") as g:
    foodlist=g.read().splitlines()
    for item in foodlist:
        food,value = item.split(': ')
        foodDict.update({food:value})
    for food in relations.keys():
        # (Raw) Ingredients with no left hand side value in relations.txt will not change here.
        value = 0.
        for item2 in range(len(relations[food])):
            # Calculating new value for complex here.
            value += relations[food][item2][0]* float(foodDict[relations[food][item2][1]])
        foodDict.update({food: value })

# Altering the food.txt with the new dictionary values 
with open("food.txt",'w') as g:
    for key in sorted(foodDict.keys()):
        g.write(key + ': ' + str (foodDict[key])+ '\n')
        print key + ': ' + str(foodDict[key])

它出来了:

eggs: 2
onions: 1
omelette: 11.0
pileofomelettes: 66.0

您可以在food.txt文件中将鸡蛋价格更改为5,

eggs: 5
onions: 1
omelette: 26.0
pileofomelettes: 156.0