2017-05-15 5 views
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')) 

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 

答えて

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

Python3では、zipは反復可能性を返します。最初の呼び出し後、zipの結果が消費されました。このようzip()を使用

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')) 

:あなたは

>>> 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

あなたの問題は、このラインである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'))) 

それは小さい例を参照する方が簡単です結果からlistを作成することができます最初は良い考えのように思えるかもしれません。あなたはあなたのリストを一度だけ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それらを一緒に:

for integer, numeral in zip(ints, numerals) 

しかし、可能であれば私は、@ John La Rooyがすでに言っているように、zip()の結果をリストにキャストすることができます。これにより、結果を複数回使用して、zip()への繰り返し呼び出しを避けることができます。

関連する問題