Finding Lowest Value Within A Nested List?
Solution 1:
Nesting One Deep
In your example, the list is nested only one deep. If this is the case in general, then try:
>>>list2 = [3,4,[2,99,8],7]>>>min(x ifisinstance(x, int) elsemin(x) for x in list2)
2
Nesting of Arbitrary Depth
If deeper nesting is allowed, define this recursive function:
>>>defrmin(lst): returnmin(x ifisinstance(x, int) else rmin(x) for x in lst)...
In operation:
>>>rmin(list2)
2
Or, with deeper nesting:
>>>list3 = [3,4,[[2,99],8],7]>>>rmin(list3)
2
>>>list4 = [3, 4, [[2, [99, 1]], 8], 7]>>>rmin(list4)
1
How it works
The function rmin
consists of the single line:
returnmin(x ifisinstance(x, int) else rmin(x) for x in lst)
As you can see, this is a list comprehension that looks at every value x
of the list lst
.
Let's divide the argument of min
into two parts. The first is:
x if isinstance(x, int) else rmin(x)
This returns x
if x
is an integer. Otherwise, it calls rmin
on x
. In the latter case, rmin
recursively looks at every value in x
and returns the minimum.
The second part of the argument of min
is:
forxin lst
This is just the usual for a list comprehension. It extracts each value in lst
in turn and assigns it to x
.
Solution 2:
In general, you could flatten your list of lists and search for min in the flattened list. There are many recipes for flattening. Here is one that I took from here.
import collections
defflatten(iterable):
for el in iterable:
ifisinstance(el, collections.Iterable) andnotisinstance(el, str):
yieldfrom 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
This will work on multiple nested list as well, e.g.:
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
Solution 3:
The problem is caused by the line
y=min(i)
where i
is an integer but not a list. You probably want y = min(list2[i])
.
Note that while you have appended this y
back to the original list, the loop would not reach the newly added element, since i
will only range up to the original length of the list.
With some simple Python idioms, your original idea can be expressed in a more readable way as follows:
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()
Solution 4:
When I needed to do something similar, I wrote following:
import copy
defnestedMin(list_):
target_list = copy.deepcopy(list_) # to keep original list unchangedfor index inrange (len(target_list)):
iftype (target_list[index]) islist:
target_list[index] = nestedMin(target_list[index])
returnmin(target_list)
I know that it is not very efficient, keeps doing deepcopy; but it's readable and it does the job :)
Example:
list1 = [2,3,[4, -5, [7, -20]]]
print nestedMin(list1) # prints -20print list1 # prints [2, 3, [4, -5, [7, -20]]]
Post a Comment for "Finding Lowest Value Within A Nested List?"