由于IndexError而无法遍历嵌套列表

时间:2013-07-03 07:08:17

标签: python

此代码基于我收到的question优雅答案,并按比例放大以接受最多5个元素的嵌套列表。总体目标是合并在索引位置1具有重复值的嵌套列表。

当marker_array中的嵌套列表包含4个元素时,异常传递会抑制IndexError。但是代码无法在最终输出中包含4个元素列表之后的最后一个列表。我的理解是,defaultdict的目的是首先避免IndexErrors。

# Nested list can have 4 or 5 elements per list. Sorted by [1]
marker_array = [
    ['hard','00:01','soft','tall','round'],
    ['heavy','00:01','light','skinny','bouncy'],
    ['rock','00:01','feather','tree','ball'],
    ['fast','00:35','pidgeon','random'],
    ['turtle','00:40','wet','flat','tail']]  

from collections import defaultdict
d1= defaultdict(list)
d2= defaultdict(list)
d3= defaultdict(list)
d4= defaultdict(list)

# Surpress IndexError due to 4 element list.
# Add + ' ' because ' '.join(d2[x])... create spaces between words.
try:
    for pxa in marker_array:
        d1[pxa[1]].extend(pxa[:1])
        d2[pxa[1]].extend(pxa[2] + ' ')
        d3[pxa[1]].extend(pxa[3] + ' ')
        d4[pxa[1]].extend(pxa[4] + ' ')

except IndexError:
    pass

# Combine all the pieces.
res = [[' '.join(d1[x]),
        x,
        ''.join(d2[x]),
        ''.join(d3[x]),
        ''.join(d4[x])]
        for x in sorted(d1)]

# Remove empty elements.
for p in res:
    if not p[-1]:
        p.pop()

print res

输出几乎是我所需要的:

[['hard heavy rock', '00:01', 'soft light feather ', 'tall skinny tree ', 'round bouncy ball '], ['fast', '00:35', 'pidgeon ', 'random ']]

由于我的技术水平,这个按比例放大的版本肯定失去了一些原始的优雅。关于改进此代码的任何一般性指示都非常受欢迎,但我的两个主要问题依次为:

  1. 如何确保[' turtle',' 00','湿''''& #39; tail']嵌套列表不会被忽略?
  2. 我可以做些什么来避免像柔软的羽毛一样拖尾空白?

2 个答案:

答案 0 :(得分:3)

问题是try块的放置。 IndexError不是由defaultdict引起的,而是因为您尝试访问pxa[4]的第4行中的marker_array,这不存在。

在for循环中移动你的try / except,如下所示:

for pxa in marker_array:
  try:
    d1[pxa[1]].extend(pxa[:1])
    d2[pxa[1]].extend(pxa[2] + ' ')
    d3[pxa[1]].extend(pxa[3] + ' ')
    d4[pxa[1]].extend(pxa[4] + ' ')
  except IndexError:
    pass

输出现在将包括第4行。

要回答您的第二个问题,您可以通过在每个联接上''.join()strip()来调用各种rstrip()来电来删除空白区域(例如strip(''.join(d2[x]))。< / p>

答案 1 :(得分:2)

  1. 因为你的try语句在for循环之外启动,for循环中的异常会导致程序转到except块而不会在之后返回循环。相反,将try放在循环中的主块之前:

    for pxa in marker_array:
        try:
            d1[pxa[1]].extend(pxa[:1])
            d2[pxa[1]].extend(pxa[2] + ' ')
            d3[pxa[1]].extend(pxa[3] + ' ')
            d4[pxa[1]].extend(pxa[4] + ' ')
    
        except IndexError:
            pass
    

    从技术上讲,最佳做法是在try块中包含尽可能少的代码,因此如果您确定列表永远不会少于4个项目,则可以将try块的开头向下移动到之前的行你延长了d4。

  2. 如果我正确理解了您的代码,那么您将获得尾随空格,因为您在pxa [4]之后添加了一个空格。当然,删除d4 [pxa [1]]中的空格。延伸(pxa [4] +'')使得d4 [pxa [1]]。extend(pxa [4])不能解决你的问题较短的清单。相反,你不能在pxa [3]之后添加一个空格,而是在pxa [4]之前添加一个空格,如下所示:

            d3[pxa[1]].extend(pxa[3])
            d4[pxa[1]].extend(' ' + pxa[4])
    
  3. 我认为应该解决它。