忽略StopIteration

时间:2012-08-31 19:26:55

标签: python csv error-handling stopiteration

我刚刚阅读了一些关于如何处理Python中的StopIteration错误的帖子,但我无法解决我的特定示例。基本上,我有一个带有很多前缀的csv文件。此文件有两列标题:Word和Count。 Count是该前缀出现的频率。我还有另一个包含公司名称列表的文件。前缀文件从公司文件中的每个公司名称的第一个单词获取前缀。我正在尝试删除重复项,我现在想要做的是:

每次发生此错误时,请忽略StopIteration错误。

顺便说一下,我不想写下面所有注释掉的“if”语句,而只需要一行说:如果生成StopIteration错误,只需通过处理有问题的“前缀”来忽略错误。 “好像它是在前缀文件中出现两次以上的前缀,这样我们就应该返回没有包含前缀的公司名称的值。我意识到这忽略了这样一个事实,即前缀文件中有一个不同的前缀值和公司名称的实际前缀,但通常它与在python和excel之间存储的非美国英文字母有关,还有一些其他这些方法看起来并不特别系统,所以我稍后会手动删除它们。

我的代码是:

def remove_prefix(prefix, first_name):
   #try:
   #EXCEPTIONS:
   #if '(' in prefix:
   #    prefix = prefix[1:]
      #if ')' in prefix:
    #  prefix = prefix[:-1]
    """
      if prefix == "2-10":
        prefix = "2"
      if prefix == "4:2:2":
        prefix = "4"
      if prefix == "5/0" or prefix == "5/7" or prefix == "58921-":
        prefix = "5"
    """
    #except StopIteration:
   #    pass

   print(first_name, prefix)
   input_fields = ('Word', 'Count')
   reader = csv.DictReader(infile1, fieldnames = input_fields)
   #if the prefix has a frequency of x >=2 in the prefix file, then return first_name  without prefix
   #else, return first_Name
   infile1.seek(0)
   #print(infile1.seek(0))
   next(reader)
   first_row = next(reader)
   while prefix != first_row['Word'] and prefix[1:]!= first_row['Word']:
      first_row = next(reader)
      #print(first_name, prefix)
      #print(first_row, first_name, prefix, '\t' + first_row['Word'], prefix[1:])
   if first_row['Count'] >= 2:
      length = len(prefix)
      first_name = first_name[length+1:]
  #print("first name is ", first_name)
  return first_name

2 个答案:

答案 0 :(得分:3)

我不认为这是由你认为它引起的。当生成器(reader)用完行以读取时,会导致StopIteration异常。

例如:

def g():
    "generates 1 (once)"
    yield 1

a = g()
next(a) # is 1
next(a) # StopIteration exception (nothing left to yield)

要解决此问题,您可以尝试将next包裹起来,除了(传递):

while prefix != first_row['Word'] and prefix[1:]!= first_row['Word']:
    try:
        first_row = next(reader)
    except StopIteration:
        pass

然而,正如大卫指出的那样,这可能不是你应该采取的方式。

答案 1 :(得分:2)

这可以通过首先从文件创建前缀列表,然后在每个上使用startswith方法以更简单的方式完成。例如:

reader = csv.DictReader(infile1)
# # this is assuming there are only two columns in the file: Word and Count
prefixes = [l["Word"] for l in list(reader) if int(l["Count"]) >= 2]

def remove_prefix(first_name):
    for p in prefixes:
        if first_name.startswith(p):
            return first_name[len(p):]
    return first_name

这不会更简单吗?另一个优点是它只读取文件一次,而不是为它想要替换的每个单词重新打开它。