Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 理解中的压缩功能_Python_List_List Comprehension - Fatal编程技术网

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