Python 产生所有元素都是整数的元组
我正在编写一个函数,它接收一个元组的iterable,然后我必须生成所有元素都是int的元组。其中包括以下条件: 对于元组中的每个元素:Python 产生所有元素都是整数的元组,python,list,Python,List,我正在编写一个函数,它接收一个元组的iterable,然后我必须生成所有元素都是int的元组。其中包括以下条件: 对于元组中的每个元素: 如果是int,则保持不变 如果是str,则将其转换为int(如果可能,请参见下面的示例) 否则,返回None For example: list(func([(1, "48")])) = [(1, 48)] list(func([(1, "0xf")])) = [(1, 15)] list(func([(1, "junk")])) = None lis
- 如果是int,则保持不变
- 如果是str,则将其转换为int(如果可能,请参见下面的示例)
- 否则,返回None
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新手,非常感谢您的帮助:)我的(未经测试的)想法:
我假设“对于元组中的每个元素”,如果无法转换为int,那么对于该元素,而不是整个元组,您将返回None
[更新]
现在您已经更新了问题,如果希望
func([(1,“垃圾”)])
在输入的任何地方出现任何不可转换的项目时返回None
,那么使用yield
是没有意义的;yield
的全部要点是在计算值时立即开始返回值。对于所需的输出,必须保留结果,直到处理整个列表。也许你误读了你的作业?这有点奇怪,但看起来你想处理任何Python整数文本格式,就好像它是int
一样。最好的方法可能是调用ast.literal\u 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
-like和int
-可转换但实际上不int
的事物执行什么操作,以获得int
-like的适当定义
现在,您只需执行以下操作:
try:
return tuple(intify(x) for x in iterable)
except ValueError:
return None
如果您想对整个iterable执行此操作,则需要一个嵌套循环,如下所示:
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)
或者,如果您没有Python 3.3:
for subiterable in iterable:
yield tuple(intify(x) for x in subiterable)
这将在第一个错误值上引发异常。因此,如果您只是使用迭代器来传递对list
的调用,则部分构建的列表将被放弃以处理异常
再说一次,如果你用这个函数做的唯一一件事就是建立一个列表,那么你根本没有理由首先使用生成器;只要返回一个列表。Python相信“如果是鸭子,那就是鸭子”。最好对每个元素调用int(),并捕获异常,而不是使用isinstance。我不禁注意到,在这次尝试中,明显缺少了
yield
。你知道什么是yield
--我很确定列表构造函数在任何情况下都不会返回None。我仍然不认为您理解了yield
的意义。这将产生一大堆None
值,如果有任何坏值,则引发异常;否则,它将只产生一个值。您所需的输出与此完全不同。这遗漏了所有奇怪的十六进制逻辑。我将把所需的“to_int”函数作为练习留给OP,我只是演示如何组织代码,而不是做他的家庭作业。:-)我喜欢这个答案,但有一个快速的警告,你真的得到了python的ints视图。例如,“010”是8。因此,请确保你的前导零思想符合python的思想。@tdelaney:我认为这正是OP想要的。或者,如果不是Python的ints视图,那么可能是JavaScript或C或chmod
命令或其他东西。但我当然可能错了。(另外,请注意,010
在Python3中不是8
,它是一个SyntaxError
,正是因为他们认为避免混淆比解析C文本更重要。)因此70年代的字符串约定最终在Python3中消失了。我想也许是时候扔掉PDP-11参考手册了。@tdelaney:但是如果没有PDP-11参考手册,你怎么会记得现在字节是8位而不是9位呢?:)@AdamSmith:二进制文字,1972年?这是每个单词19个字符,而不是7个!你在磁带公司有股票吗?
for subiterable in iterable:
yield tuple(intify(x) for x in subiterable)