产生所有元素都是整数的元组

时间:2014-09-16 21:36:20

标签: python list

我正在编写一个接收可迭代元组的函数,然后我必须得到所有元素都是整数的元组。其中条件:

对于元组中的每个元素:

  • 如果是int,请保持不变
  • 如果是str,则将其转换为int(如果可能,请参见下面的示例)
  • 否则,返回无

    For example: 
    
    list(func([(1, "48")])) = [(1, 48)]
    list(func([(1, "0xf")])) = [(1, 15)]
    list(func([(1, "junk")]))  = None
    list(func([([3], 4)])) = None
    

到目前为止,这是我的代码,看起来很讨厌并且无法正常工作

 def func(iterable):
     for x in iterable:
        for i in x:
           if not ((isinstance(i, str) and i.isdigit()) or (isinstance(i, str) and isinstance(int(i, 16), int)) or isinstance(i, int)):
              yield None
      yield [i if isinstance(i, int) else int(i) if i.isdigit() else int(i, 16) for i in x for x in iterable]

你有更好的解决方案>?我是python的新手,非常感谢任何帮助:)

2 个答案:

答案 0 :(得分:4)

这有点奇怪,但看起来你想要处理任何Python整数文字格式,好像它是一个int。最好的方法是调用ast.literal_eval来解析它,然后查看它是否解析为int。像这样:

def intify(x):
    if isinstance(x, int):
        return x
    parsed = ast.literal_eval(x)
    if isinstance(parsed, int):
        return parsed
    raise ValueError('{} is not an int literal'.format(x))

请注意,您可能希望改为测试isinstance(x, numbers.Integral),如果是,则返回int(x),或者只要成功返回int(x),或者根据您的不同返回int想要处理int - 和int - 可兑换但实际上不是int的内容,对于try: return tuple(intify(x) for x in iterable) except ValueError: return None 的某些适当定义 - 就像。

现在,您只需执行此操作:

try:
    return [tuple(intify(x) for x in subiterable) for subiterable in iterable]
except ValueError:
    return None

如果你想为可迭代的整个迭代执行此操作,则需要一个嵌套循环,如下所示:

None

如果你想懒散地做这件事,在没有建立清单的情况下产生元素,就没有办法“早退”并返回yield from (tuple(intify(x) for x in subiterable) for subiterable in iterable) - 一旦你已经产生了一些价值,你就不能unyield他们。所以,你想要的并不是直接可能的。但如果你能解释为什么你想要它,那么同样有用的东西实际上可能是可行的。例如:

for subiterable in iterable:
    yield tuple(intify(x) for x in subiterable)

或者,如果您没有Python 3.3:

list

这将在第一个错误值上引发异常。因此,如果您只是使用迭代器传递给{{1}}的调用,则将放弃部分构建的列表来处理异常。

然后再说一次,如果你正在使用这个函数做的唯一事情是建立一个列表,那么首先没有理由使用生成器;只需返回一个清单。

答案 1 :(得分:0)

我(未经测试)拍摄:

def to_int(item):
    try:
        return int(item)
    except ValueError:
        return None

def func(iterable):
    for input_tuple in iterable:
        yield tuple(to_int(item) for item in input_tuple)

我假设“对于元组中的每个元素”如果无法转换为int,则将为该元素返回None,而不是整个元组。

[更新]

现在您已更新了问题,如果您希望yield在输入的任何位置出现任何不可转换的项目时func([(1, "junk")])返回None,则无法使用yield。 {{1}}的重点是在计算它们后立即开始返回值。对于所需的输出,您必须保留结果,直到您处理整个列表。也许你误解了你的任务?