从一个列表的列表中选取一个项目

5

我是一个新手,对Python不是很熟悉,现在有一个作业让我感到困难。我收到了一个由数字和单词“none”组成的列表嵌套列表,例如:

 [[1,None],[2,4],[1.5,2]]

我的问题是当我遍历到None时(我需要对列表求和),我需要将其替换为其他列表中同一位置的最大数字。 因此,我的结果应该是None = max(4,2)并且接收:

 [[1,4],[2,4],[1.5,2]]

如果我使用for循环,我不知道如何去检查其他的子列表(特别是当我不知道有多少个子列表时)。


1
这是一个包含单词“'none'”或Python中的NoneType的字符串吗? - R Nar
你是说每次出现 None,它都会被所有列表中的最大数替换掉? - Totem
None = 非字符串的NoneType,每个None都会被替换为相同位置子列表中的最大值(其他位置可能存在None)。 - Macsim
我这个程序的初始目标是将每个子列表相加,函数需要返回最低的一个。 - Macsim
请编辑您的问题,展示您编写的循环,并描述哪些部分有效以及哪些部分无效。目前,您正在请求别人为您完成作业。抽象地说,您可以通过循环遍历数据...如果您的数据是列表,则可以通过循环遍历它...并且您可以在迭代时测试您所拥有的数据。 - dsh
显示剩余2条评论
7个回答

2
使用带有条件的嵌套列表推导式
>>> l =  [[1,None],[2,4],[1.5,2]]
>>> def findMax(j):
...     return max(i[j] for i in l)
... 
>>> [[j if j is not None else findMax(k) for k,j in enumerate(i)] for i in l]
[[1, 4], [2, 4], [1.5, 2]]

这里的列表推导式检查每个元素是否为空。如果不是,则打印该数字,否则找到最大值并打印该元素。

使用 map 的另一种方法是

>>> l =  [[1,None],[2,4],[1.5,2]]
>>> maxVal = max(map(max, l))
>>> [[j if j is not None else maxVal for k,j in enumerate(i)] for i in l]
[[1, 4], [2, 4], [1.5, 2]]

3
j!=None 翻译为 j is not None,意思相同但更符合Python的惯用语法。 - Anentropic
2
有趣的解决方案,但可能对 OP 来说有点难以理解,因为他表示是 Python 新手 :) - OneCricketeer
@cricket_007 哈哈,说得好。这将有两个好处。1. OP 将学到一些新东西 2. 其他人也会对此感兴趣(就像你一样)。 - Bhargav Rao
是的,我明白了。我进行了一些更符合Python风格的编辑。 - OneCricketeer
很高兴能够帮忙,@Macsim。如果您认为已经解决了您的问题,请接受一个答案。这将有助于社区认可正确的解决方案。您可以通过点击答案旁边的绿色勾号来完成此操作。参见此图片以供参考。祝好! - Bhargav Rao
显示剩余5条评论

1

这里有个提示:在Python中,for in循环遍历某个可迭代对象中的所有元素。如果你有一个列表嵌套列表,那么列表中的每个元素也可以应用于for循环,就像在for循环内部嵌套了另一个for循环一样。只有当列表的最大深度为2时才能使用此方法:

def get_deep_max(deeplst):
   new = []
   for elem in deeplst:
      for num in elem:
         new.append(num)
   return max(new)

尝试自己编写代码来替换空值,以便进行练习。


是的,我理解for循环的基本用法,我的问题主要是当我在for循环中遍历子列表时,如何停止计数并同时转到其他子列表。 - Macsim

1

代码:

for idx1, sublist in enumerate(list1):
    for idx2, element in enumerate(sublist):
        if element is None:
          try:
             sublist[idx2] = max(list1[idx1+1])
          except IndexError:
             pass

问题在于,如果最后一个列表中有None,您没有指定代码应该执行什么操作。我只是添加了一个tryexcept。您可以将pass替换为您希望代码执行的操作。

是的,它是一个None而不是字符串。谢谢。 - Macsim

1
我的建议:
x = [[1,None],[2,4],[1.5,2]] #your list
highest_num = None  # assume that 0 can be the highest number in a different situation
for each in x:`# find the highest number
   for another in each:
        if another > highest_num:
            highest_num = another
for each in xrange(len(x)): # find the None and replace it with the highest number
    for another in xrange(len(x[each])):
        if x[each][another] is None:
            x[each][another] = highest_num

1
from contextlib import suppress


l = [[1,None],[2,4],[1.5,2]]

for sub in l:
    with suppress(ValueError):
        i = sub.index(None)  # find index of None in sublist (or ValueError)
        sub[i] = max(s[i] for s in l if s[i] is not None)  # replace sublist item with max of sublists in same index
        break

print(l)
# [[1, 4], [2, 4], [1.5, 2]]

谢谢,我不知道“suppress”操作。 - Macsim

1
这个相比其他的更易读(我个人认为)。
l = [[1,None],[2,4],[1.5,2]]
maxVal = max(map(max, l)) # maps the function 'max' over all the sub-lists
for subl in l:
    for idx,elem in enumerate(subl): # use enumerate to get the index and element
        if elem is None:
            subl[idx] = maxVal
print l
# [[1, 4], [2, 4], [1.5, 2]]

1
这是我的建议:
l = [[1, None], [2, 4], [1.5, 2]]
# l = [[1, None], [2, 4], [1.5, 2]]
l1 = zip(*l)
# l1 = [(1, 2, 1.5), (None, 4, 2)]
m = map(max, l1)
# m = [2, 4]
l2 = [map(lambda y: m[i] if y is None else y, x) for i,x in enumerate(l1)]
# l2 = [[1, 2, 1.5], [4, 4, 2]]
ret = zip(*l2)
# ret = [(1, 4), (2, 4), (1.5, 2)]

是的,zip()是Python中的内置函数:https://docs.python.org/2/library/functions.html#zip - simpel01

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接