[英]What is the Pythonic or best practice way of iterating over an integer?
在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)它只是感觉完全不优雅。 有没有其他方法来处理这个问题? 我是否完全以错误的方式处理这些函数,即我是否应该迭代整数?
谢谢你的帮助。
我个人觉得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
我更喜欢我的变体而不是你的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中进行。
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))
如果您的数字不是“大规模” - 即停止运行,那么您可以将has_even_digit
用作:
>>> a = 123456789
>>> any(i % 2 == 0 for i in map(int, str(a)))
True
如果不这样做,优化就是按1
自身按位 - 因为如果第一个位置位,任何可由二进制表示的东西都必须是奇数。 虽然这涉及“整数” - 而不是数字。
你可以创建一个生成器:
def digits(num):
while num > 0:
yield num % 10
num /= 10
如果只是将它们存储到单独的变量中,则可以轻松减轻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
def has_even_digits(n):
return bool(set('02468') & set(str(n)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.