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

迭代整数的Pythonic或最佳实践方法是什么?,python,casting,type-conversion,Python,Casting,Type Conversion,在Python中迭代整数的最佳实践是什么?我发现我需要经常这样做,通常会有详细的结果。例如,下面是我为解决问题编写的两个函数: 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

在Python中迭代整数的最佳实践是什么?我发现我需要经常这样做,通常会有详细的结果。例如,下面是我为解决问题编写的两个函数:

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)感觉完全不雅观。有没有其他办法处理这个问题?我是否以完全错误的方式处理这些函数,也就是说,我是否应该不必迭代整数


谢谢你的帮助。

我个人觉得str(n)中e的
非常可读

我确实发现,对
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
如果你的数字不是“巨大的”-即,使事情停止,那么你可以使用你的
has\u偶数数字作为:

>>> a = 123456789
>>> any(i % 2 == 0 for i in map(int, str(a)))
True

如果不能做到这一点,优化将是使用
1
本身按位进行,因为如果设置了第一位,则二进制表示的任何内容都必须是奇数。尽管这与“整数”有关,而不是数字。

对于偶数数字的迭代,您可以使用参数:

范围(开始、结束、步骤)

因此,在代码中,您可以执行以下操作:


对于范围(0,8,2)内的e:

您可以创建一个生成器:

def digits(num):
    while num > 0:
        yield num % 10
        num /= 10

我更喜欢我的变体而不是你的
的排列:

def is_perm(a,b): return sorted(str(a)) == sorted(str(b))
我认为这对于
有偶数位数的人来说更好

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。如果您只需将其存储到单独的变量中,is_置换的计算成本很容易降低

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

我同意。通常,有一个可读的解决方案比一个优雅的解决方案要好。@NPE,我同意这一行是相当可读的,但一旦你做了这样的事情,它就会变得混乱:
对于范围内的e(len(str(n))
@ggundersen:但是你为什么要这样做呢?当然您只需要使用
enumerate()
?如果只需要迭代索引,为什么要使用
enumerate(x)
<代码>xrange(len(x))
对我来说似乎更好。当然,
str(n)
并不是从一开始就得到以10为基数的数字的可数的最佳方法。@NPE,我对Pyson说了同样的话:我很欣赏这些优化,但我认为它忽略了我更大的问题,那就是:我应该不迭代整数吗?我发布的函数只是我认为迭代有用的例子。请注意:
是('aab','abb')的置换。
将返回
True
@poke,感谢您在下面两条评论中的观察,你似乎在问“我可以在不将int转换为str的情况下执行这些函数吗?”你可能可以,用类似C的方式,但为什么?将int转换为字符串是脚本语言中的一个重要习惯用法和快捷方式。如果你认为它更快——它可能不是。而且肯定会有更多的代码。整数是不可数的,所以你刚才提到的问题没有多大意义。在阅读了详细信息之后,您实际上是在讨论对整数中的数字进行迭代。在这种情况下,执行字符串转换自然是下一步。但是没有必要在for循环中一遍又一遍地重复,只需在顶部添加一个
ndigits=str(n)
就足够了。@thewolf,这正是我要问的。从各种答案来看,将整数转换为字符串似乎是对数字进行迭代的python方式。谢谢。这两个都是不错的@Pyson,但函数只是我迭代整数的例子;你是说根本不存在这样的情况,还是只是在改进我的功能?不管怎样,谢谢。
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))
def has_even_digits(n):
    return bool(set('02468') & set(str(n)))