我正在编写一个接收可迭代元组的函数,然后我必须得到所有元素都是整数的元组。其中条件:
对于元组中的每个元素:
否则,返回无
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的新手,非常感谢任何帮助:)
答案 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}}的重点是在计算它们后立即开始返回值。对于所需的输出,您必须保留结果,直到您处理整个列表。也许你误解了你的任务?