在嵌套列表中找到最低值?
Posted
技术标签:
【中文标题】在嵌套列表中找到最低值?【英文标题】:Finding lowest value within a nested list? 【发布时间】:2015-01-31 11:08:15 【问题描述】:我正在尝试编写一个函数,该函数接受一个列表并可以打印该列表中的最小整数。现在我试图弄清楚在嵌套列表的情况下该做什么,如果最小的数字在这些嵌套列表之一内,那么总体上它将打印该数字。我的代码在这里:
def listMin():
list2 = [3,4,[2,99,8],7]
for i in range (len(list2)):
if type(list2[i]) == type([]):
y=min(i)
list2.append(y)
print "hello"
if len(list2)== 0:
return None
else:
x= min(list2)
print x
listMin()
虽然这似乎应该打印数字 2,但它没有打印,并且一旦到达嵌套列表就会给我一个错误:
TypeError: 'int' object is not iterable
我尝试了多种方法,但我很难理解为什么这种方法不起作用。
【问题讨论】:
【参考方案1】:嵌套一深
在您的示例中,列表仅嵌套一层。如果是这种情况,请尝试:
>>> list2 = [3,4,[2,99,8],7]
>>> min(x if isinstance(x, int) else min(x) for x in list2)
2
任意深度的嵌套
如果允许更深的嵌套,定义这个递归函数:
>>> def rmin(lst): return min(x if isinstance(x, int) else rmin(x) for x in lst)
...
运行中:
>>> rmin(list2)
2
或者,使用更深的嵌套:
>>> list3 = [3,4,[[2,99],8],7]
>>> rmin(list3)
2
>>> list4 = [3, 4, [[2, [99, 1]], 8], 7]
>>> rmin(list4)
1
工作原理
函数rmin
由单行组成:
return min(x if isinstance(x, int) else rmin(x) for x in lst)
如您所见,这是一个列表推导式,它查看列表 lst
的每个值 x
。
让我们将min
的参数分成两部分。第一个是:
x if isinstance(x, int) else rmin(x)
如果x
是整数,则返回x
。否则,它会在x
上调用rmin
。在后一种情况下,rmin
递归查看x
中的每个值并返回最小值。
min
的第二部分参数是:
for x in lst
这只是列表理解的常用方法。它依次提取lst
中的每个值并将其分配给x
。
【讨论】:
【参考方案2】:一般来说,您可以展平列表并在展平的列表中搜索 min。有很多扁平化的食谱。这是我从here 获取的。
import collections
def flatten(iterable):
for el in iterable:
if isinstance(el, collections.Iterable) and not isinstance(el, str):
yield from flatten(el)
else:
yield el
list2 = [3,4,[2,99,8],7]
print(list(flatten(list2)))
# [3, 4, 2, 99, 8, 7]
print(min(flatten(list2)))
# 2
这也适用于多个嵌套列表,例如:
list2 = [3,4,[2,99,8,[-1,-2]],7]
print(list(flatten(list2)))
# [3, 4, 2, 99, 8, -1, -2, 7]
print(min(flatten(list2)))
# -2
【讨论】:
【参考方案3】:问题是线路引起的
y=min(i)
其中i
是一个整数,但不是一个列表。你可能想要y = min(list2[i])
。
请注意,虽然您已将此 y
附加回原始列表,但循环不会到达新添加的元素,因为 i
的范围只能达到列表的原始长度。
通过一些简单的 Python 习语,你的原始想法可以用更易读的方式表达如下:
def listMin():
lst = [3,4,[2,99,8],7]
for x in lst:
if type(x) == list:
lst.append(min(x))
print min(lst)
listMin()
【讨论】:
是的,但它不会只是该语句中的一个列表,因为 if 语句是如果原始列表中该元素的类型是一个列表,那么找到该列表的最小值并将其附加到 list2?list2[i]
是该声明中的列表,是的;但i
仍然是整数索引。【参考方案4】:
当我需要做类似的事情时,我写了以下内容:
import copy
def nestedMin(list_):
target_list = copy.deepcopy(list_) # to keep original list unchanged
for index in range (len(target_list)):
if type (target_list[index]) is list:
target_list[index] = nestedMin(target_list[index])
return min(target_list)
我知道效率不高,一直在做deepcopy;但它是可读的,它可以完成工作:)
例子:
list1 = [2,3,[4, -5, [7, -20]]]
print nestedMin(list1) # prints -20
print list1 # prints [2, 3, [4, -5, [7, -20]]]
【讨论】:
以上是关于在嵌套列表中找到最低值?的主要内容,如果未能解决你的问题,请参考以下文章