函数调用中的循环与显式列出所有参数之间的区别
Difference between a loop in a function call and listing all the arguments explicitly
我有一个函数可以按第一个列表对列表列表进行排序。当我像这样使用带有变量的函数时:
sort_lists(IN[0],IN[1],IN[2])
它工作得很好。虽然,因为我不知道我的输入包含多少列表,所以我想将其用作我的变量:
sort_lists(IN[idx] for idx in range(len(IN)))
尽管这 returns 是对一个列表(超级列表)的排序。为什么这些变量之间存在差异,我该如何改进代码?
这里是函数if decisive(这里IN[0]是带有多个子列表的输入):
def sort_lists(*args):
zipped_list= zip(*sorted(zip(*args)))
return [list(l) for l in zipped_list]
OUT = sort_lists(data_sort[0],data_sort[1],data_sort[2])
我想使用这个输出:
OUT = sort_lists(data_sort[idx] for idx in range(len(IN[0])))
只是将函数更改为接受列表列表,有问题吗?这段代码:
IN[idx] for idx in range(len(IN))
returns 再列表列表
这里有两点需要理解:
*args
会给你所有函数参数 as a tuple
IN[idx] for idx in range(len(IN))
是一个 generator expression
如果您只需在函数中添加 print
语句,您就可以看到您的输入有何不同:
def sort_lists(*args):
print(args)
zipped_list= zip(*sorted(zip(*args)))
return [list(l) for l in zipped_list]
令列表的输入列表为:lists = [[2, 1, 3], [1, 3, 4], [5, 4, 2]]
.
sort_lists(lists[0], lists[1], lists[2])
将打印:([2, 1, 3], [1, 3, 4], [5, 4, 2])
。那是一个内部列表的元组。
不过,如果你这样称呼它:
sort_lists(lists[idx] for idx in range(len(lists)))
或
sort_lists(sublist for sublist in lists)
这将打印 (<generator object <genexpr> at 0x0000007001D3FBA0>,)
,一个生成器的单元素元组。
您可以通过仅接受一个参数使您的函数与生成器一起工作:
def sort_lists(arg):
zipped_list= zip(*sorted(zip(*arg)))
return [list(l) for l in zipped_list]
sort_lists(lists[idx] for idx in range(len(lists)))
# [[1, 2, 3], [3, 1, 4], [4, 5, 2]]
但我建议保留您的函数原样,unpack您的列表在您调用它的地方:
>>> sort_lists(*lists)
[[1, 2, 3], [3, 1, 4], [4, 5, 2]]
正如 Georgy 所指出的,区别在于参数是生成器还是列表。我还要指出,这是一个使用和练习map
方法的机会。 map
对列表中的每个条目应用相同的函数。该函数可以是内置函数,例如 sorted
.
list_a = [[2, 1, 3], [1, 3, 4], [5, 4, 2]]
sorted_list_a = list(map(sorted, list_a)) # sorted is the python built-in function
print(sorted_list_a)
Returns:
[[1, 2, 3], [1, 3, 4], [2, 4, 5]]
您会注意到,您必须将 map
传递给 list
函数,因为 map
returns 是一个地图对象,所以您必须转它进入一个列表。
map documentation is here. And a good example of it is here.
我有一个函数可以按第一个列表对列表列表进行排序。当我像这样使用带有变量的函数时:
sort_lists(IN[0],IN[1],IN[2])
它工作得很好。虽然,因为我不知道我的输入包含多少列表,所以我想将其用作我的变量:
sort_lists(IN[idx] for idx in range(len(IN)))
尽管这 returns 是对一个列表(超级列表)的排序。为什么这些变量之间存在差异,我该如何改进代码?
这里是函数if decisive(这里IN[0]是带有多个子列表的输入):
def sort_lists(*args):
zipped_list= zip(*sorted(zip(*args)))
return [list(l) for l in zipped_list]
OUT = sort_lists(data_sort[0],data_sort[1],data_sort[2])
我想使用这个输出:
OUT = sort_lists(data_sort[idx] for idx in range(len(IN[0])))
只是将函数更改为接受列表列表,有问题吗?这段代码:
IN[idx] for idx in range(len(IN))
returns 再列表列表
这里有两点需要理解:
*args
会给你所有函数参数 as a tupleIN[idx] for idx in range(len(IN))
是一个 generator expression
如果您只需在函数中添加 print
语句,您就可以看到您的输入有何不同:
def sort_lists(*args):
print(args)
zipped_list= zip(*sorted(zip(*args)))
return [list(l) for l in zipped_list]
令列表的输入列表为:lists = [[2, 1, 3], [1, 3, 4], [5, 4, 2]]
.
sort_lists(lists[0], lists[1], lists[2])
将打印:([2, 1, 3], [1, 3, 4], [5, 4, 2])
。那是一个内部列表的元组。
不过,如果你这样称呼它:
sort_lists(lists[idx] for idx in range(len(lists)))
或
sort_lists(sublist for sublist in lists)
这将打印 (<generator object <genexpr> at 0x0000007001D3FBA0>,)
,一个生成器的单元素元组。
您可以通过仅接受一个参数使您的函数与生成器一起工作:
def sort_lists(arg):
zipped_list= zip(*sorted(zip(*arg)))
return [list(l) for l in zipped_list]
sort_lists(lists[idx] for idx in range(len(lists)))
# [[1, 2, 3], [3, 1, 4], [4, 5, 2]]
但我建议保留您的函数原样,unpack您的列表在您调用它的地方:
>>> sort_lists(*lists)
[[1, 2, 3], [3, 1, 4], [4, 5, 2]]
正如 Georgy 所指出的,区别在于参数是生成器还是列表。我还要指出,这是一个使用和练习map
方法的机会。 map
对列表中的每个条目应用相同的函数。该函数可以是内置函数,例如 sorted
.
list_a = [[2, 1, 3], [1, 3, 4], [5, 4, 2]]
sorted_list_a = list(map(sorted, list_a)) # sorted is the python built-in function
print(sorted_list_a)
Returns:
[[1, 2, 3], [1, 3, 4], [2, 4, 5]]
您会注意到,您必须将 map
传递给 list
函数,因为 map
returns 是一个地图对象,所以您必须转它进入一个列表。
map documentation is here. And a good example of it is here.