问题
The following [incomplete] code is designed to take in an n to x number, of length x-n, and return the value of the next pandigital number. The code identifies which number between n and x is missing from the number passed in as an argument to the function, and returns (for the time being, until the function is further developed), two lists, the original number itself with its individual digits as members of a list, and a list, with the numbers n to x as members, with those numbers which are present in the original number of length x-n being replaced by the Boolean value True.
def nextPandigital(n,lower,upper):
digits = []
requiredDigits = []
#Completed loop
for digit in str(n):
digits.append(int(digit))
#Completed loop
for num in range(lower,upper+1):
requiredDigits.append(num)
for number in requiredDigits:
if str(number) in str(digits):
x = requiredDigits.index(number)
#requiredDigits[x] = 'True'
requiredDigits[x] = True
return digits, requiredDigits
Although, for the input parameters of nextPandigital(1023456789,0,9)
in Enthought Canopy, the second list returned should read [True,True,True,True,True,True,True,True,True,True]
, the value of the second list returned is, in fact [True,1,True,True,True,True,True,True,True,True]
, with the 1 from the original requiredDigits
list not being replaced by True
.
I know that there is no issue with the loop, or the general flow of the code, for when the requiredDigits[x] = True
line of code is commented, and the currently commented code is uncommented, the code works as it is intended to, with all digits in requiredDigits
being replaced by the String value 'True.
'
I have attempted to resolve this issue. However, I am not able to pinpoint its source. I have considered to fact that True == 1
returns True. However, when the value True is replaced by False, in the line requiredDigits[x] = True
, the code still works as it is intended to.
Any answer/help/suggestion/advice on this matter would be highly appreciated. Thank you in advance.
回答1:
The issue is with using index
to find where to assign to. Since True
is equal to 1, you're mistakenly thinking that the True
you entered for 0
is the 1
you want to replace next.
A solution would be to use enumerate
to get indexes as you iterate over your list, rather than needing to find them later using index
:
for x, number in enumerate(requiredDigits):
if str(number) in str(digits):
requiredDigits[x] = True
A better solution in general would be to use a list comprehension to create the list in one go, rather than starting with numbers and replacing some of them later:
requiredDigits = [True if num in digits else num for num in range(lower,upper+1)]
I'm also getting rid of the unnecessary calls to str
in the membership test against digits
. You were doing substring testing, rather than testing if the numbers themselves were in the list. That probably wasn't going to cause errors, since the numbers you care about are all one digit long, and the string representation of a list doesn't have any extraneous digits. But in general, its not a good idea to use string operations when you don't need to.
回答2:
You are checking the same list that you are updating and that is always dangerous.
At the second iteration your variables are:
number=1
requiredDigits = [True, 1, 2, 3, 4, 5, 6, 7, 8, 9]
So when you are doing requiredDigits.index(1)
there is a match but it does not reach the 1
since it happens in True==1
so it returns that the index 0
But in general, this implementation is not much pythonic, better check Blckknght's answer
来源:https://stackoverflow.com/questions/37524346/python-lists-append-true-boolean