我一直在研究一个罗马数字转换器,它一直循环直到被告知退出并且它在第一次迭代时起作用。之后变量只是空的,它可能与我指定它的位置有关吗?
代码:
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
答案 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()
。