繁体   English   中英

迭代整数的Pythonic或最佳实践方法是什么?

[英]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自身按位 - 因为如果第一个位置位,任何可由二进制表示的东西都必须是奇数。 虽然这涉及“整数” - 而不是数字。

对于偶数位数的迭代,您可以使用范围的step参数:

range(start, end, step)

所以,在你的代码中,你可以这样做:

for e in range(0, 8, 2):

你可以创建一个生成器:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM