我正在尝试比较来自两个不同文件的列的数据。我尝试使用for
,现在使用list comprehension
。
问题是外部for循环没有被迭代,但内部循环不是。我已单独检查,迭代就好了;但是一旦我窝了,我就会遇到这个问题。我有什么遗漏吗?
import csv
newInv = csv.reader(open("new.csv", "r"))
origInv = csv.reader(open("old.csv", "r"))
print [ oldrow[5] + " " + newrow[3] for oldrow in origInv for newrow in newInv ]
答案 0 :(得分:9)
请注意,在你的解决方案中,for循环是嵌套的,所以这就是为什么一个循环似乎迭代而另一个循环似乎没有。
一次获取两个迭代器的一个元素需要用itertools.izip
:
[ oldrow[5] + " " + newrow[3]
for oldrow, newrow in itertools.izip(origInv, newInv)]
答案 1 :(得分:3)
外部是迭代的。但是,内部循环仅针对外部循环的第一次迭代执行 - 然后已到达newInv的结尾。
了解newInv
不是可以多次迭代的集合。它是一个只能使用一次的迭代器。试试这个(未经测试):
newInv = list(csv.reader(open("new.csv", "r")))
origInv = list(csv.reader(open("old.csv", "r")))
将数据复制到内存中,允许您多次迭代。
答案 2 :(得分:3)
这里有两件事情。
1)你的列表理解中有两次迭代。从概念上讲,您要求为每newInv
重复oldrow
。
2)你没有看到(oldRow,newRow)的每一个组合的原因,就像你给出的第一点一样,是csv.reader
是流,因此只能迭代一次。 newInv
之后的每次“迭代”都没有找到新项目,因为它们都是第一次“用完”。
首先从每个list
获取(旧行,新行),csv.reader
的每个组合(您可以将它们直接传递给list
构造函数。
要获得一对(旧行,新行),zip
两个csv.reader
的成对组合序列。
答案 3 :(得分:1)
这可能是括号中的一个简单问题。
print [[(expression with i and j) for i in foo] for j in bar]
答案 4 :(得分:1)
来自文档
itertools.product(*iterables[, repeat])
Cartesian product of input iterables.
等效于生成器表达式中的嵌套for循环。例如,对于B中的y,乘积(A,B)的返回值与(x中的x的(x,y)相同)。
嵌套循环像里程表一样循环,最右边的元素在每次迭代时前进。此模式创建了一个字典顺序,以便在输入的可迭代内容进行排序时,产品元组按排序顺序发出。
要计算iterable与其自身的乘积,请使用可选的repeat关键字参数指定重复次数。例如,产品(A,repeat = 4)表示与产品(A,A,A,A)相同。
此函数等效于以下代码,但实际实现不会在内存中构建中间结果:
def product(*args, **kwds):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
2.6版中的新功能。