在python中找到没有重复数字的年份

时间:2015-03-09 23:32:18

标签: python digits repeat

我试图在没有重复数字的情况下找到最近5年,并且我一直收到错误'int' object has no attribute '__getitem__'

这是我的代码而我到目前为止 - 我无法弄清楚它有什么问题。关于如何修复它的任何解释都表示赞赏。

def find_year():
    start = 2015
    years = []
    while len(years) < 5:
        if start[0] == start[1]:
            return False
        elif start[0] == start[2]:
            return False
        elif start[0] == start[3]:
            return False
        elif start[1] == start[2]:
            return False
        elif start[1] == start[3]:
            return False
        elif start[2] == start[3]:
            return False
        else:
            years.append(start)
            start -= 1
     else:
          print years

 find_year()

4 个答案:

答案 0 :(得分:5)

您假设您可以索引([])一个整数来获取数字,但这不是您可以用Python中的整数做的事情。你可以做的是将整数转换为字符串,然后你可以索引字符串以从中获取字符:

>>> year = 2015
>>> year_as_string = str(year)
>>> year_as_string[0]
'2'

错误消息提及属性__getitem__的原因是year[0]基本上扩展为year.__getitem__(0)Info on __getitem__

另外,我建议在较小的部分解决这个问题。而不是试图立即解决整个问题,首先编写一个一年年的函数,如果它没有任何重复数字,则返回TrueFalse除此以外。然后,当你有了这个工作时,你可以编写另一个函数来调用循环中的第一个函数来获得你需要的五个结果。

有几种很好的方法可以解决完整的问题:

列表理解:

>>> [y for y in range(2015, 0, -1) if len(set(str(y))) == 4][0:5]
[2015, 2014, 2013, 1987, 1986]

迭代器:

from itertools import islice
>>> list(islice(filter(lambda y: len(set(str(y))) == 4, range(2015, 0, -1)), 5))
[2015, 2014, 2013, 1987, 1986]

列表理解更简单,但做了更多的工作(它将在范围内尝试所有年份,但只丢掉前五个除外);迭代器版本不是那么简单,但(在Python 3中)只能完成所需的工作量。

答案 1 :(得分:3)

这是一个列表理解的单行:

[year for year in range(2015, 1915, -1) if len(set(str(year)))==4] [0:5]

[2015, 2014, 2013, 1987, 1986]

您可以使用len(set(str(year)))==4测试无重复数字。 range(2015, 1915, -1)限制了我们需要测试的年数。 然后我们只用[0:5]对结果进行切片,得出前五个这样的年份(从2015年起按降序排列)。

答案 2 :(得分:0)

这可能有用,试试吧:

    >> from collections import Counter

    >> year = 2015
    >> list = map(int, str(year))
    >> counts = Counter(list)
    >> counts
      Counter({0: 1, 1: 1, 2: 1, 5: 1})
    >>Counter(list).values()
     [1,1,1,1]

最后一种方法将计算年中每个数字的出现次数。这应该更有效率。 现在,如果您想知道是否有重复的数字,请使用此post

>> import bisect

>> bisect.bisect(Counter(list).values(), 1)
4

任何低于4的值意味着有一个数字出现多次。

答案 3 :(得分:0)

问题是您无法使用[]索引表示法访问整数的数字。一种简单的方法是将其转换为数字序列,并且检查重复的简单方法是将该序列转换为set并检查集合的长度是否与数字,如果有任何重复,则不会是这样 - 请参阅answer其他相关问题。

以下代码可以查看从起始年开始的前几年和未来年份。它还检查起始年份,但是你的问题是否应该这样做是不明确的。

def has_dup_digits(year):
    """ Check if integer year has any repeated digits.
    """
    digits = str(year)
    return len(digits) != len(set(digits))

def find_years(start_year):
    """ Find the 5 years closest to the starting year without repeated digits.
    """
    years = []
    if not has_dup_digits(start_year): # check start year
        years.append(start_year)
    delta = 1
    while len(years) < 5:
        if not has_dup_digits(start_year+delta):
            years.append(start_year+delta)
        if len(years) >= 5:
            break
        if not has_dup_digits(start_year-delta):
            years.append(start_year-delta)
        delta += 1

    print(sorted(years))

find_years(2015)  # --> [2013, 2014, 2015, 2016, 2017]