仅用于循环列表中的第二项。 (蟒蛇)

时间:2012-04-13 11:31:45

标签: python coding-style for-loop nested-lists

我拥有什么

是这样的

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],而不是将它分配给一个新的变量然后事情变得一团糟。

new to to python如果我遗漏了一些明显的东西,那就很抱歉

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:2)

当然,itertools.chainslicing何时会提供帮助?

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)

答案 3 :(得分:1)

虽然我喜欢Dikei's answer的清晰度和简洁性,但我仍然认为一个好的选择就是:

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

请记住,除非真的需要速度,否则速度应始终位于可读性的第二位。

答案 4 :(得分: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