在Python中迭代整数的最佳做法是什么?我发现我需要经常这样做,通常是详细的结果。例如,以下是我为Project Euler问题编写的两个函数:
def is_permutation_of(n, m):
""" Return True if n is a permutation of m, else False
"""
if len(str(n)) != len(str(m)):
return False
for d in str(n):
if d not in str(m):
return False
return True
另一个:
def has_even_digit(n):
""" Return True if n has an even digit, else False
"""
evens = ['0', '2', '4', '6', '8']
for e in evens:
if e in str(n):
return True
return False
除了详细程度之外,1)必须有与每种类型转换相关的计算费用; 2)它只是感觉完全不优雅。有没有其他方法来处理这个问题?我是否完全以错误的方式处理这些函数,即我是否应该迭代整数?
感谢您的帮助。
答案 0 :(得分:3)
我个人认为for e in str(n)
非常易读。
我发现不太引人注意的是重复调用str(n)
内部循环(其中n
是不变的。)
无论如何,我会以完全不同的方式实现这两个功能
def is_permutation_of(n, m):
return sorted(str(n)) == sorted(str(m))
def has_even_digit(n):
if n == 0:
return True
while n != 0:
if n % 2 == 0:
return True
n //= 10
return False
答案 1 :(得分:3)
我更喜欢我的变体而不是is_permutation_of
:
def is_perm(a,b): return sorted(str(a)) == sorted(str(b))
我认为这对has_even_digit
def has_even_digit(n):
evens=set(['0', '2', '4', '6', '8'])
return any(c in evens for c in str(n))
或者,甚至使用元组而不是集合:
def has_even_digit(n):
return any(c in ('0', '2', '4', '6', '8') for c in str(n))
修改强>
在评论主题中,我想找到这样的东西:
# pseudo code -- don't use -- not syntactically correct
for d in 123456: # integer
# do something with each digit...
这不起作用,因为整数不支持Python中的迭代。此外,没有真正需要像整数迭代这样的东西,因为它是如此惯用并且易于使用字符串。
这是一个使用字符串来创建单个整数位的Python框架:
for d in [int(c) for c in str(123456)]:
# d is a left (most significant) to right integer digit - do what you want with it...
如果您想从右到左使用相同的数字:
for d in [int(c) for c in str(123456)[::-1]]:
# Now right (least significant digit) to left (most significant digit)
将这两个简单的情况与使用整数或长整数的实际数学进行比较:
def int_iter(n,reverse=False):
rtr=[]
if not isinstance(n, (int,long)):
raise ValueError('n must be int or long')
while n:
rtr.append(n%10)
n/=10
if reverse:
return rtr[::-1]
else:
return rtr
使用字符串真的要容易得多,而且可能更快。如果你需要超快的速度,请在C中进行。
答案 2 :(得分:2)
def is_permutation_of(n, m):
return sorted(n) == sorted(m)
evens=re.compile('[02468]')
def has_even_digit(n):
return evens.search(str(n))
答案 3 :(得分:1)
如果您的号码不是“大规模” - 即停止播放,那么您可以将has_even_digit
用作:
>>> a = 123456789
>>> any(i % 2 == 0 for i in map(int, str(a)))
True
如果失败,优化将是1
本身的按位 - 因为如果第一位被设置,二进制表示的任何东西都必须是奇数。虽然这与“整数”有关 - 而不是数字。
答案 4 :(得分:0)
答案 5 :(得分:0)
您可以创建一个生成器:
def digits(num):
while num > 0:
yield num % 10
num /= 10
答案 6 :(得分:0)
如果只是将它们存储到单独的变量中,则可以轻松减轻is_permutation_of的计算成本。
def is_permutation_of(n, m):
""" Return True if n is a permutation of m, else False
"""
sn = str(n)
sm = str(m)
if len(sn) != len(sm):
return False
for d in sn:
if d not in sm:
return False
return True
答案 7 :(得分:0)
def has_even_digits(n):
return bool(set('02468') & set(str(n)))