5

是)我有的

是这样的

def mymethod():
    return [[1,2,3,4],
            [1,2,3,4],
            [1,2,3,4],
            [1,2,3,4]]

mylist = mymethod()

for _, thing, _, _ in mylist:
    print thing

# this bit is meant to be outside the for loop, 
# I mean it to represent the last value thing was in the for
if thing:
    print thing

我想要的是

我想要做的是避免使用虚拟变量,有没有比这更聪明的方法

for thing in mylist:
    print thing[1]

因为那样我将不得不在thing[1]我需要它的任何其他时间使用它,而不将它分配给一个新变量,然后事情就会变得一团糟。

如果我遗漏了一些明显的东西,那么对 python 来说很抱歉

4

5 回答 5

7

你可以破解生成器表达式

def mymethod():
    return [[1,2,3,4],
            [1,2,3,4],
            [1,2,3,4],
            [1,2,3,4]]

mylist = mymethod()

for thing in (i[1] for i in mylist):
    print thing

# this bit is meant to be outside the for loop, 
# I mean it to represent the last value thing was in the for
if thing:
    print thing
于 2012-04-13T11:35:36.967 回答
3

如果要获取数组的第二列,可以使用列表推导,如下所示:

a = [ [ 1, 2, 3, 4 ],
      [ 5, 6, 7, 8 ],
      [ 9,10,11,12 ],
      [13,14,15,16 ] ]


second_column = [ row[1] for row in a ]
# you get [2, 6, 10, 14]

您可以将其包装在一个函数中:

def get_column ( array, column_number ):
    try:
        return [row[column_number] for row in array]
    except IndexError:
        print ("Not enough columns!")
        raise # Raise the exception again as we haven't dealt with the issue.

fourth_column = get_column(a,3)
# you get [4, 8, 12, 16]

tenth_column = get_column(a,9)
# You requested the tenth column of a 4-column array, so you get the "not enough columns!" message.

虽然实际上,如果您正在使用数字的矩形数组,那么您希望使用numpy数组,而不是数字列表的列表。


或者,根据 Lattyware 的隐含请求,生成器版本:

def column_iterator ( array, column_number ):
    try:
        for row in array:
            yield row[column_number]
    except IndexError:
        print ("Not enough columns!")
        raise

用法就像一个普通的列表:

>>> for item in column_iterator(a,1):
...    print(item)
... 
2
6
10
14
>>> 

发电机的性质通过以下方式显而易见:

>>> b = column_iterator(a,1)
>>> b.next()
2
>>> b.next()
6
>>> b.next()
10
>>> b.next()
14
于 2012-04-13T11:51:33.833 回答
2

当然,itertools.chain切片什么时候会派上用场?

for thing in itertools.islice(itertools.chain(*mylist),1,None,len(mylist)):
    print(thing)

Numpy 也有助于列切片。这是 numpy 中的另一个示例

for thing in numpy.array(mylist)[:,1]:
    print(thing)
于 2012-04-13T11:39:07.903 回答
1

虽然我喜欢Dikei 的清晰和简洁的回答,但我仍然认为一个好的选择很简单:

for sublist in mylist:
    item = sublist[1]
    ...
    do_stuff(item)
    ...
    do_other_stuff(item)
    ...

它仍然很清楚,可以扩展为更容易做,并且可能是最快的。

这里有一些快速测试——由于在循环中什么都不做,我不确定它们的准确度,但它们可能会给出一个想法:

python -m timeit -s "mylist = [range(1,8) for _ in range(1,8)]" 'for thing in mylist:' '    item=thing[1]' '    pass'
1000000 loops, best of 3: 1.25 usec per loop

python -m timeit -s "mylist = [range(1,8) for _ in range(1,8)]" 'for thing in (i[1] for i in mylist):' '    pass'
100000 loops, best of 3: 2.37 usec per loop

python -m timeit -s "mylist = [range(1,8) for _ in range(1,8)]" 'for thing in itertools.islice(itertools.chain(*mylist),1,None,len(mylist)):' '    pass'
1000000 loops, best of 3: 2.21 usec per loop

python -m timeit -s "import numpy" -s "mylist = numpy.array([range(1,8) for _ in range(1,8)])" 'for thing in mylist[:,1]:' '    pass' 
1000000 loops, best of 3: 1.7 usec per loop

python -m timeit -s "import numpy" -s "mylist = [range(1,8) for _ in range(1,8)]" 'for thing in numpy.array(mylist)[:,1]:' '    pass'
10000 loops, best of 3: 63.8 usec per loop

请注意,如果一旦生成 numpy 会很快,但对于单个操作按需生成则非常慢。

在大型列表中:

python -m timeit -s "mylist = [range(1,100) for _ in range(1,100)]" 'for thing in mylist:' '    item=thing[1]' '    pass'
100000 loops, best of 3: 16.3 usec per loop

python -m timeit -s "mylist = [range(1,100) for _ in range(1,100)]" 'for thing in (i[1] for i in mylist):' '    pass'
10000 loops, best of 3: 27 usec per loop

python -m timeit -s "mylist = [range(1,100) for _ in range(1,100)]" 'for thing in itertools.islice(itertools.chain(*mylist),1,None,len(mylist)):' '    pass'
10000 loops, best of 3: 101 usec per loop

python -m timeit -s "import numpy" -s "mylist = numpy.array([range(1,100) for _ in range(1,100)])" 'for thing in mylist[:,1]:' '    pass'
100000 loops, best of 3: 8.47 usec per loop

python -m timeit -s "import numpy" -s "mylist = [range(1,100) for _ in range(1,100)]" 'for thing in numpy.array(mylist)[:,1]:' '    pass'
100 loops, best of 3: 3.82 msec per loop

请记住,速度应该始终排在可读性之后,除非您真的需要它。

于 2012-04-13T11:51:23.697 回答
1

该方法itemgetter()可用于解决此问题:

from operator import itemgetter

def mymethod():
    return [[1,2,3,4],
            [1,2,3,4],
            [1,2,3,4],
            [1,2,3,4]]

mylist = mymethod()

row = map(itemgetter(2), mylist)
print("row %s" % row)

thing = row[-1]

# this bit is meant to be outside the for loop, 
# I mean it to represent the last value thing was in the for
if thing:
    print thing

输出是:

row [3, 3, 3, 3]
3
于 2012-04-13T13:03:47.470 回答