变量在整个过程中的某个地方失去了它的价值

时间:2017-05-15 04:00:22

标签: python loops while-loop

我一直在研究一个罗马数字转换器,它一直循环直到被告知退出并且它在第一次迭代时起作用。之后变量只是空的,它可能与我指定它的位置有关吗?

代码:

num_array = zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1),
('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'))

def int_to_roman(i):
    result = []
    for integer, numeral in num_array:
        count = int(i / integer)
        result.append(numeral * count)
        i -= integer * count
    return ''.join(result)

def roman_to_int(n):
    result = 0
    i = result
    for integer, numeral in num_array:
        while n[i:i + len(numeral)] == numeral:
            result += integer
            i += len(numeral)
    return result

x = ""
while x != "quit":
    x = ""
    x = input("enter number to be converted or quit to stop ")
    if x == "quit":
        break
    else:
        if x.isdigit():
            x = int(x)
            print(x, 'is',(int_to_roman(x)))
            print(' ')
        else:
            if x.isalpha():
                print(x,'is',(roman_to_int(x)))
                print(' ')

输出:

enter number to be converted or quit to stop C
C is 100

enter number to be converted or quit to stop C
C is 0

enter number to be converted or quit to stop 

3 个答案:

答案 0 :(得分:2)

在Python3中,zip返回一个可迭代的。第一次调用后,zip的结果已被消耗。您可以从list的结果

创建zip
num_array = list(zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1),
                ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V',
                 'IV', 'I')))

使用较小的示例

更容易看到
>>> nums = zip((1, 2, 3, 4), ('A', 'B', 'C', 'D'))
>>> nums
<zip object at 0x7f5a860cba08>
>>> for item in nums:
...     print(item)
... 
(1, 'A')
(2, 'B')
(3, 'C')
(4, 'D')
>>> for item in nums:   # Nothing left in zip object
...     print(item)
... 
>>> nums = list(zip((1, 2, 3, 4), ('A', 'B', 'C', 'D')))
>>> nums
[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D')]
>>> for item in nums:
...     print(item)
... 
(1, 'A')
(2, 'B')
(3, 'C')
(4, 'D')
>>> for item in nums:   # Can loop over a list as many times as you like
...     print(item)
... 
(1, 'A')
(2, 'B')
(3, 'C')
(4, 'D')
>>> 

答案 1 :(得分:1)

这一行:

num_array = zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1),
                ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V',
                 'IV', 'I'))

创建一个迭代器。迭代迭代器后,就完成了。它不会再次迭代。您需要在每次需要迭代时创建zip,或者将迭代器的结果存储到列表或元组中。

答案 2 :(得分:1)

你的问题就在这一行:

num_array = zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1),
('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'))

首先使用这样的zip()似乎是一个好主意。您只需{1}}一次您的列表。正确?

然而,这种逻辑是错误的。 zip()返回一个迭代器。一旦迭代器耗尽(即你迭代它一次),它就完成了。你不能再使用它了。您可以通过查看zip()的源代码示例来自行查看:

zip()

除了使用def zip(*iterables): # zip('ABCD', 'xy') --> Ax By sentinel = object() iterators = [iter(it) for it in iterables] while iterators: result = [] for it in iterators: elem = next(it, sentinel) if elem is sentinel: return result.append(elem) yield tuple(result) 一次之外,每次迭代时都应该将元组压缩在一起:

首先创建你的元组:

zip()

然后ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1) numerals = ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I') 他们在一起:

zip

然而,正如@John La Rooy已经说过的那样,一个可能更加自觉的灵魂就是将for integer, numeral in zip(ints, numerals) 的结果简单地投射到一个列表中。这样,您可以多次使用结果,避免重复调用zip()