在嵌套列表中找到最低值?

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]]]

【讨论】:

以上是关于在嵌套列表中找到最低值?的主要内容,如果未能解决你的问题,请参考以下文章

在嵌套列表中查找元素,但是我们不知道该列表

WPF - 嵌套列表框绑定不起作用

计算嵌套字典中列表的平均值

如何找到所有可见的深层嵌套 ListView 项目?

查找列表中有多少嵌套字典键

搜索特定值的嵌套字典列表[重复]