Python 理解中的压缩功能
我将Python 理解中的压缩功能,python,list,list-comprehension,Python,List,List Comprehension,我将l=['1','2','3','rt4','rt5']作为输入,并将其转换为l=[1,2,3,'rt4','rt5'],代码如下: def RepresentsInt(s): try: int(s) return True except ValueError: return False l=['1','2','3','rt4','rt5'] l=[int(l[i]) if RepresentsInt(l[i]) else l
l=['1','2','3','rt4','rt5']
作为输入,并将其转换为l=[1,2,3,'rt4','rt5']
,代码如下:
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
l=['1','2','3','rt4','rt5']
l=[int(l[i]) if RepresentsInt(l[i]) else l[i] for i in range(0,len(l))]
我可以通过理解来改进上面的代码吗?您想要的东西确实不清楚,但可能类似于:
>>> l=['1','2','3','rt4','rt5']
>>> l=[int(i) if i.isdigit() else i for i in l]
>>> l
[1, 2, 3, 'rt4', 'rt5']
您可以将
RepresentsInt
函数更改为实际返回整数(如果可能的话),这将使操作更简单:
def RepresentsInt(s):
try:
return int(s)
except ValueError:
return s
然后,转换列表的代码可以写成(在l循环中使用for item可能比在索引上迭代要好):
或者,如果您想将其作为一个可重用模式,您仍然需要一个helper函数(我在这里选择了一种类似于decorator的方法),因为您不能使用try
和/或,除非在理解中使用s:
def try_to_apply_func(func, exception):
def newfunc(value):
try:
return func(value)
except exception:
return value
return newfunc
>>> to_int_if_possible = try_to_apply_func(int, ValueError)
>>> [to_int_if_possible(item) for item in l]
[1, 2, 3, 'rt4', 'rt5']
>>> to_float_if_possible = try_to_apply_func(float, ValueError)
>>> [to_float_if_possible(item) for item in l]
[1.0, 2.0, 3.0, 'rt4', 'rt5']
我不相信(尽管我最终可能是错的)有一个更干净、更整洁的方法来实现这一点。一种解决方案是创建一个整数解析lambda
表达式,如下所示,但我认为您当前的解决方案更简洁、更健壮
>>> l = ['1','2','3','rt4','rt5']
>>> l = list(map(lambda s : (s.isdigit() or (s[0] == '-' and s[1:].isdigit())) and int(s) or s, l))
>>> l
[1, 2, 3, 'rt4', 'rt5']
这不会正确捕获字符串,例如'1.0'
或'1'
,但它应该在两行中完成您想要的功能。您可以使用以下代码来获得所需的结果
l = ['1','2','3','rt4','rt5']
l = [int(each) if each.isdigit() else each for each in l]
print l
您不能在表达式中使用异常处理(列表理解是一个表达式,只能包含其他表达式),因此您想要的是不可能的。您可以将自己限制为只包含数字的字符串,并使用str.isdigit()
,但这不完全是同一回事。您为什么要使用list(map(lambda s:
)而不是list comprehension?而且,您的代码不工作,您缺少了)
。哎呀,我的错。而且我不知怎么开始使用映射了(
语法非常普遍,只是在这里应用它而没有真正思考。西红柿,西红柿我猜。除了你的西红柿更长更慢:-)是的。例如timeit('a中的x为x','a=[0]*100')
大约需要2.5秒,timeit('list(map(lambda x:x,a)),'a=[0]*100'))
花费了我大约7.9秒的时间。下半部分还有更多的想法(尽管这是map+lambda vs generator expression)。map本身就是一个不同的故事。map+lambda组合通常很糟糕(特别是如果你甚至需要一个列表(…)
)。如果您已经有了一个函数,那么映射它是很好的,例如,map(int,mystrings)
。在Python 2中,map
接受None
作为函数,并且它映射的时间与其给定的最长iterable一样长,这两种方法都需要更多的代码而不使用map
。
l = ['1','2','3','rt4','rt5']
l = [int(each) if each.isdigit() else each for each in l]
print l