使用分数时Python中的内存错误

时间:2018-03-28 21:50:52

标签: python python-3.x fractions

我使用stern-brocot序列来生成分数。这些分数已附加到列表中。现在我需要修改这个分数列表,因为问题要求我满足列表中存在的分数的2个条件。

1)对于列表中存在的每个简化分数a/bb/2a也必须存在。

2)每2个简化分数a/bc/d(a+b)/(c+d)  也应该出席。

我已经写了下面的代码就可以了。

# Python program to print 
# Brocot Sequence
from fractions import Fraction

import math

class MyFraction:  # This class has been defined to return unsimplified fractions as they are as the'd get simplified using the fractions module
    def __init__(self, numerator=1, denominator=1):
        self.numerator = numerator
        self.denominator = denominator

    def get_fraction(self):
        return Fraction(numerator=self.numerator, denominator=self.denominator)

    def __repr__(self):
        return '{}/{}'.format(self.numerator, self.denominator)


def SternSequenceFunc(BrocotSequence, n):

    # loop to create sequence
    for i in range(1, n):

        considered_element = BrocotSequence[i]
        precedent = BrocotSequence[i-1]

        # adding sum of considered
        # element and it's precedent
        BrocotSequence.append(considered_element + precedent)

        # adding next considered element
        BrocotSequence.append(considered_element)


    # printing sequence..
     for i in range(0, n):
        print(BrocotSequence[i] , end=" ")

     print("\n")

# Function to determine if a fraction is simplified or not

def is_simplified(frac):

    if frac == Fraction(frac.numerator, frac.denominator):

        return True

    else:

        return False

# Function to modify the set to satisfy the given conditions

def modify_set(list_fractions):

    # To satisfy the 1st condition
    for fraction in list_fractions:
        numerator = fraction.numerator
        denominator = fraction.denominator
        list_fractions.append(MyFraction(denominator, 2*numerator))

    # To satisfy the 2nd condition
    for fraction in list_fractions:
        if is_simplified(fraction):
            for frac in list_fractions:
                if frac != fraction:
                    if is_simplified(frac):
                        f = MyFraction((fraction.numerator+frac.numerator), (fraction.denominator+frac.denominator))
                        list_S.append(f)

while True: 

    list_S = []

    count = 0
    # Driver code
    n = int(input("Enter value of n : "))
    BrocotSequence = []

    # adding first two element
    # in the sequence
    BrocotSequence.append(1)
    BrocotSequence.append(1)

    SternSequenceFunc(BrocotSequence, n)

    for i in range(1, n):
        list_S.append(Fraction(BrocotSequence[i], BrocotSequence[i-1])) # Appending the list with fractions generated from stern-brocot sequence

    modify_set(list_S)

    print("\n Printing all fractions : \n")
    for fraction in list_S:
        count = count + 1
        print("\n", fraction)

    print("Number of fractions: {}".format(count))

运行此代码后,我在运行Memory Error函数时得到modify_set。我不明白为什么。任何人都可以帮助我理解为什么以及如何解决这个问题?

提前致谢。

1 个答案:

答案 0 :(得分:1)

在此处迭代时,您正在添加list

for fraction in list_fractions:
    numerator = fraction.numerator
    denominator = fraction.denominator
    list_fractions.append(MyFraction(denominator, 2*numerator))

每次从list_fractions中提取一个元素,然后添加一个新元素(最终将依次迭代)。所以这个循环永远不会结束,list永远增长(或者直到MemoryError)。

同样地,在你的那个函数的下一个循环中(并不是你能够达到它),你已经在list_fractions上得到了一个嵌套循环,虽然它不那么明显在这里,它也将是无限的,因为每次迭代都附加到list_S(这是一个全局的),它作为list_fractions参数传递,因此它们都是同一个{{i}的别名1}}(Python函数调用不要复制其参数的内容,只复制引用本身,因此除了将list重新绑定到新对象之外的任何内容都会修改list_fractions

我不知道您的预期逻辑,但如果目标是仅为现有条目添加新条目(而不是处理添加的条目),则解决方案是迭代{的浅表副本{1}},例如:

list_S

你的嵌套循环会更复杂(取决于内循环是否应该处理list的更新副本);我将让您确定正确的行动方案。