简体   繁体   English

嵌套for循环(list comprehension)在python中; 外循环不循环

[英]Nested for loop (list comprehension) in python; outer loop not looping

I am trying to compare data from columns from two different files. 我试图比较来自两个不同文件的列的数据。 I've attempted to use a for , and now a list comprehension . 我试图使用for ,现在是list comprehension

The issue is that the outer for loop is not being iterated through, but the inner one is. 问题是外部for循环没有被迭代,但内部循环不是。 I've checked individually and iteration is just fine; 我已单独检查,迭代就好了; but once I nest I get this issue. 但是一旦我窝了,我就会遇到这个问题。 Is there something I missing with this? 我有什么遗漏吗?

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 ]

Note that in your solution the for loops are nested, so that's why one loop seems to iterate while the other one doesn't seem to. 请注意,在您的解决方案中,for循环是嵌套的,因此这就是为什么一个循环似乎迭代而另一个循环似乎没有。

What you need to use to get one element of both iterators at a time is itertools.izip : 你需要使用什么来一次获得两个迭代器的一个元素是itertools.izip

[ oldrow[5] + " " + newrow[3]
for oldrow, newrow in itertools.izip(origInv, newInv)]

The outer is iterated. 外部是迭代的。 However, the inner loop is only executed for the first iteration of the outer loop - then the end of newInv has been reached. 但是,内循环仅在外循环的一次迭代中执行 - 然后到达newInv的结尾。

Understand that newInv is not a set that you can iterate over multiple times . 了解newInv 不是可以多次迭代的集合 It is an iterator that you can use only once. 它是一个只能使用一次的迭代器。 Try this (untested): 试试这个(未经测试):

newInv  = list(csv.reader(open("new.csv", "r")))
origInv = list(csv.reader(open("old.csv", "r")))

which will copy the data into memory and allow you to iterate over multiple times. 它会将数据复制到内存中,并允许您多次迭代。

There are two things going on here. 这里有两件事。

1) Your list comprehension has two iterations in it. 1)你的列表理解有两个迭代。 Conceptually, you are asking to re-iterate over newInv for every oldrow . 从概念上讲,你要求再次重申了newInv为每oldrow

2) The reason you don't see every combination of (oldRow, newRow), like you'd expect given the first point, is that a csv.reader is a stream , and thus can only be iterated over once. 2)你没有看到(oldRow,newRow)的每个组合的原因,就像你期望的第一点一样, csv.reader是一个 ,因此只能迭代一次。 Each subsequent "iteration" over newInv finds no new items, because they were all "used up" the first time. newInv每个后续“迭代” newInv没有找到新项目,因为它们都是第一次“用完”。

To get every combination of (old row, new row), form list s from each csv.reader first (you can pass them directly to the list constructor. 首先从每个csv.reader获取(旧行,新行)表单list的每个csv.reader (您可以将它们直接传递给list构造函数。

To get one sequence of pair-wise combinations of (old row, new row), zip the two csv.reader s together. 要获得(旧行,新行)的一对组合序列,请将两个csv.reader zip在一起。

这可能是括号中的一个简单问题。

print [[(expression with i and j) for i in foo] for j in bar]

From the docs 来自文档

itertools.product(*iterables[, repeat])
Cartesian product of input iterables.

Equivalent to nested for-loops in a generator expression. 等效于生成器表达式中的嵌套for循环。 For example, product(A, B) returns the same as ((x,y) for x in A for y in B). 例如,乘积(A,B)与A中的x的((x,y)相同,对于B中的y,返回相同的值)。

The nested loops cycle like an odometer with the rightmost element advancing on every iteration. 嵌套循环像里程表一样循环,最右边的元素在每次迭代时前进。 This pattern creates a lexicographic ordering so that if the input's iterables are sorted, the product tuples are emitted in sorted order. 此模式创建了一个词典排序,以便在输入的可迭代内容进行排序时,产品元组按排序顺序发出。

To compute the product of an iterable with itself, specify the number of repetitions with the optional repeat keyword argument. 要计算iterable与其自身的乘积,请使用可选的repeat关键字参数指定重复次数。 For example, product(A, repeat=4) means the same as product(A, A, A, A). 例如,产品(A,重复= 4)表示与产品(A,A,A,A)相同。

This function is equivalent to the following code, except that the actual implementation does not build up intermediate results in memory: 此函数等效于以下代码,但实际实现不会在内存中构建中间结果:

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)

New in version 2.6. 2.6版中的新功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM