【问题标题】:reduce - 'int' object is not iterablereduce - 'int' 对象不可迭代
【发布时间】:2017-03-23 10:33:40
【问题描述】:

假设我有一些数据存储为

"this is row -1 and column -1 with value", 12345

在 csv 文件中。 (不是实际上那样存储的,点是csv中的第一个值是一个包含必要坐标的字符串。)

我现在想提取这些值。我可以做一个for r in rows: ...,但我想用一个reduce来做。

import numpy as np
import scipy as sp
from functools import reduce
import csv
import re


def load(filename):
    with open(filename,'r') as f:
        rows = csv.reader(f)
        next(rows)  # skip header
        coordi,coordj,values = reduce(
                lambda aux,r: ([aux[0]+[i], aux[1]+[j], aux[2] + [int(r[1])]] for i,j in [int(d) for d in re.findall(r"\d+", r[0])]),
                rows,
                [[],[],[]]
                )

        return coordi, coordj, values

这会产生一个

TypeError: 'int' 对象不可迭代

自从

def load(filename):
    with open(filename,'r') as f:
        rows = csv.reader(f)
        next(rows)  # skip header
        coordi,coordj,values = reduce(
                lambda aux,r: ([aux[0]+[-1], aux[1]+[-1], aux[2] + [int(r[1])]]),
                rows,
                [[],[],[]]
                )

        return coordi, coordj, values

有效,我只能猜测i,j python 不满意。

我不知道为什么,因为

for r in rows:
   i,j = [int(d) for d in re.findall(r"\d+", row[0])]

像魅力一样工作。

我该如何进行这项工作?

【问题讨论】:

    标签: python mapreduce fold iterable-unpacking


    【解决方案1】:

    嗯,i, j 有一些东西是 Python 不满意的,那是因为你传递的是一件事而不是两件事。

    你的内部列表理解的结果是一个整数列表;您无法使用 for i, j in ... 对其进行迭代。

    编辑

    for r in rows 将每一行的整个分配给r;在这种情况下,r 是一个元素列表。但是for i, j in ... 尝试迭代其参数,并且对于每个元素,它尝试将第一个成员分配给 i 并将第二个成员分配给 j;但根本就没有第一个或第二个成员,只有一个int。您正在尝试在没有迭代的地方添加额外的迭代级别。

    如果你正好有两个整数,那么你根本不应该迭代。这不能表示为列表推导,可能应该是一个单独的函数而不是 lambda:

    def reduction(aux, r):
       i,j = [int(d) for d in re.findall(r"\d+", r[0])]
       return [aux[0]+[i], aux[1]+[j], aux[2] + [int(r[1])]]
    

    【讨论】:

    • 是的,我可以,因为该列表中恰好有两个整数?或者如果你是对的,为什么for r in rows:... 版本有效?
    • 另外,如果值的数量不匹配,错误信息会不会有所不同?
    • 哇,终于明白你的意思了。男孩,我觉得自己很愚蠢。 :P 谢谢。
    【解决方案2】:

    @Daniel Roseman 是对的。在调试模式下检查 For 循环。

    下面的代码可能会对你有所帮助。

    【讨论】:

    • 嗯......我想我可以通过将[int(d) for d in re.findall(r"\d+", r[0])] 放在一个列表中(即[[int(d) for d in re.findall(r"\d+", r[0])]])来绕过这个。但后来我得到'generator' object not subscriptable。你不会碰巧知道解决这个问题的方法吗?
    • 检查 int(d) 和 r[0] 的值。其中任何一个都可能会增加错误。在错误行中使用断点进行调试将帮助您更快地解决错误。
    猜你喜欢
    • 2013-08-02
    • 2012-06-21
    • 1970-01-01
    • 2017-09-11
    • 2015-04-14
    • 1970-01-01
    • 2022-07-01
    相关资源
    最近更新 更多